local extension = Package("aaa_steam2")
extension.extensionName = "aaa_steam"

local U = require "packages/utility/utility"
local RUtil = require "packages/aaa_fenghou/utility/rfenghou_util"
local DIY = require "packages/diy_utility/diy_utility"

Fk:loadTranslationTable{
  ["aaa_steam2"] = "steam2",
}


local zhangrangzhaozhong = General(extension, "steam__zhangrangzhaozhong", "han", 3)

local steam__jiedang = fk.CreateTriggerSkill{
  name = "steam__jiedang",
  events = {fk.EventPhaseEnd},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target == player and player.phase == Player.Play and not player:isKongcheng() then
      local cards = player:getCardIds("h")
      local cardtype = Fk:getCardById(cards[1]):getTypeString()
      if not table.contains(player:getTableMark("@steam__jiedang-turn"), cardtype.."_char") then
        return table.every(cards, function (id)
          return Fk:getCardById(id):getTypeString() == cardtype
        end)
      end
    end
  end,
  on_use = function(self, event, target, player, data)
    if player:isKongcheng() then return end
    local cards = player:getCardIds("h")
    player.room:addTableMark(player, "@steam__jiedang-turn", Fk:getCardById(cards[1]):getTypeString().."_char")
    player:showCards(cards)
    player:gainAnExtraPhase(Player.Play)
  end,
}
zhangrangzhaozhong:addSkill(steam__jiedang)

local steam__qiechong = fk.CreateActiveSkill{
  name = "steam__qiechong",
  anim_type = "switch",
  switch_skill_name = "steam__qiechong",
  card_num = 0,
  target_num = 1,
  prompt = function(self)
    return "#steam__qiechong_"..Self:getSwitchSkillState(self.name, false, true)
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    local to = Fk:currentRoom():getPlayerById(to_select)
    if #selected == 0 and to and to_select ~= Self.id then
      if Self:getSwitchSkillState(self.name, false) == fk.SwitchYang then
        return not to:isKongcheng()
      else
        return not to:isNude()
      end
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local to = room:getPlayerById(effect.tos[1])
    local cards = {}
    local isYang = player:getSwitchSkillState(self.name, true) == fk.SwitchYang
    local returnToPile = function ()
      cards = table.filter(cards, function (id) return room:getCardArea(id) == Card.Processing end)
      if #cards > 0 then
        cards = table.reverse(cards)
        room:moveCards({ ids = cards, toArea = Card.DrawPile, moveReason = fk.ReasonPut, skillName = self.name })
      end
    end
    if isYang then
      player:drawCards(1, self.name)
      cards = room:askForCardsChosen(player, to, 0, 2, "h", self.name)
    else
      local cid = room:askForCardChosen(player, to, "he", self.name)
      room:obtainCard(player, cid, false, fk.ReasonPrey, player.id, self.name)
      if not player.dead then
        cards = room:getNCards(4)
        room:moveCardTo(cards, Card.Processing, nil, fk.ReasonJustMove, self.name, nil, true, player.id)
        -- 展示牌应该封装fakemove
      end
    end
    if not player.dead and #cards > 0 then
      local x = #room.logic:getEventsOfScope(GameEvent.Phase, 99, function(e)
        return e.data[1] == player and e.data[2] == Player.Play
      end, Player.HistoryTurn)
      local my_cards = table.filter(player:getCardIds("h"), function(id)
        return Fk:translate(Fk:getCardById(id).trueName, "zh_CN"):len() <= x
      end)
      if #my_cards > 0 then
        local ex_cards = room:askForPoxi(player, "steam__qiechong_exchange", {
          { isYang and to.general or "Top", cards },
          { "$Hand", my_cards },
        }, {x}, true)
        if #ex_cards > 0 then
          local my_lose = {}
          for i = #ex_cards, 1, -1 do
            if table.contains(my_cards, ex_cards[i]) then
              table.insert(my_lose, table.remove(ex_cards, i))
            end
          end
          if isYang then
            U.swapCards(room, player, player, to, my_lose, ex_cards, self.name, Player.Hand)
          else
            returnToPile()
            if not player.dead then
              U.swapCardsWithPile(player, my_lose, ex_cards, self.name, "Top", false, player.id)
            end
          end
        end
      end
    end
    returnToPile()
  end,
}
zhangrangzhaozhong:addSkill(steam__qiechong)

Fk:addPoxiMethod{
  name = "steam__qiechong_exchange",
  card_filter = function(to_select, selected, data, extra_data)
    if data == nil or extra_data == nil then return false end
    local lenLimit = extra_data[1] or 0
    if table.contains(data[2][2], to_select) then
      return Fk:translate(Fk:getCardById(to_select).trueName, "zh_CN"):len() <= lenLimit
    else
      local count = 0
      for _, id in ipairs(selected) do
        if table.contains(data[1][2], id) then
          count = count + 1
        else
          count = count - Fk:translate(Fk:getCardById(id).trueName, "zh_CN"):len()
        end
      end
      return count < 0
    end
  end,
  feasible = function(selected, data, extra_data)
    if data == nil or #selected == 0 then return false end
    local count = 0
    for _, id in ipairs(selected) do
      if table.contains(data[1][2], id) then
        count = count + 1
      else
        count = count - Fk:translate(Fk:getCardById(id).trueName, "zh_CN"):len()
      end
    end
    return count == 0
  end,
  prompt = function (data, extra_data)
    if extra_data and extra_data[1] then
      return "#steam__qiechong-exchange:::"..string.format("%.0f", extra_data[1])
    end
    return " "
  end,
  default_choice = function ()
    return {}
  end,
}

Fk:loadTranslationTable{
  ["steam__zhangrangzhaozhong"] = "张让赵忠",
  ["#steam__zhangrangzhaozhong"] = "鹗踞中天",
  ["illustrator:steam__zhangrangzhaozhong"] = "Greencias",
  ["designer:steam__zhangrangzhaozhong"] = "快雪时晴",
  ["cv:steam__zhangrangzhaozhong"] = "张让",

  ["steam__jiedang"] = "结党",
  [":steam__jiedang"] = "回合每种类型限一次，出牌阶段结束时，若你手牌类型均相同，你可展示之并执行一个额外的出牌阶段。",
  ["@steam__jiedang-turn"] = "结党",

  ["steam__qiechong"] = "窃宠",
  [":steam__qiechong"] = "转换技，出牌阶段限一次，阳：你摸一张牌并观看一名其他角色至多两张手牌。阴：你获得一名其他角色一张牌并展示牌堆顶四张牌。若如此，你可用任意张牌名字数不大于X的手牌交换其中任意张牌，你因交换失去牌的牌名字数之和与获得牌的牌数须相等（X你为本回合进行的出牌阶段数量）。",
  ["#steam__qiechong_yang"] = "窃宠：摸1张牌，观看其他角色至多2张手牌",
  ["#steam__qiechong_yin"] = "窃宠：获得其他角色1张牌，展示牌堆顶4张牌",
  ["#steam__qiechong-exchange"] = "窃宠：用任意张字数不大于 %arg 的手牌交换展示牌",
  ["steam__qiechong_exchange"] = "窃宠换牌",

  ["$steam__jiedang1"] = "古人云：宦者四星，在皇之侧，正是你我。",
  ["$steam__jiedang2"] = "天家雨露重新，落在咱家怀里，自是一片赤心。",
  ["$steam__qiechong1"] = "金貂玉带蟒袍新，便是关内侯也做得。",
  ["$steam__qiechong2"] = "职掌六宫，出入荷恩，天子称咱阿父阿母。",
  ["~steam__zhangrangzhaozhong"] = "被任执钧十余年，人间威福早享尽。",
}

local tianfeng = General(extension, "steam__tianfeng", "qun", 3)

Fk:loadTranslationTable{
  ["steam__tianfeng"] = "田丰",
  ["#steam__tianfeng"] = "直言规劝",
  ["illustrator:steam__tianfeng"] = "",
  ["designer:steam__tianfeng"] = "颜渊",
}

local steam__zhengjian = fk.CreateTriggerSkill{
  name = "steam__zhengjian",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target ~= player and target.phase == Player.Start and #target:getCardIds("ej") > 0 then
      return player:canPindian(target)
    end
  end,
  on_cost = function (self, event, target, player, data)
    if player.room:askForSkillInvoke(player, self.name, nil, "#steam__zhengjian-invoke:"..target.id) then
      self.cost_data = {tos = {target.id}}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cid = room:askForCardChosen(player, target, "ej", self.name)
    room:throwCard(cid, self.name, target, player)
    if not player:canPindian(target) then return end
    local pindian = player:pindian({target}, self.name)
    if pindian.results[target.id].winner == player then
      room:setPlayerMark(target, "@@steam__zhengjian-turn", 1)
    elseif not target.dead then
      local cards = player:getCardIds("h")
      if #cards == 0 then return end
      local card = Fk:cloneCard("archery_attack")
      card:addSubcards(cards)
      card.skillName = self.name
      if target:prohibitUse(card) then return end
      local targets = table.filter(room:getOtherPlayers(target), function (p)
        return not target:isProhibited(p, card)
      end)
      if #targets == 0 then return end
      room:useCard{from = target.id, tos = table.map(targets, function(p) return {p.id} end), card = card}
    end
  end,
}
local steam__zhengjian_prohibit = fk.CreateProhibitSkill{
  name = "#steam__zhengjian_prohibit",
  is_prohibited = function (self, player, to, card)
    return player and player:getMark("@@steam__zhengjian-turn") ~= 0 and card and card.is_damage_card
  end,
}
steam__zhengjian:addRelatedSkill(steam__zhengjian_prohibit)
tianfeng:addSkill(steam__zhengjian)

Fk:loadTranslationTable{
  ["steam__zhengjian"] = "正谏",
  [":steam__zhengjian"] = "其他角色的准备阶段，你可以弃置其判定区或装备区一张牌，并与其拼点：若你没赢，其将你所有手牌当【万箭齐发】使用；若你赢，其本回合不能使用伤害类卡牌。",
  ["#steam__zhengjian-invoke"] = "正谏：你可以弃置%src场上一张牌并与其拼点，若你没赢，其将你手牌当【万箭】使用，若你赢，其本回合不能用伤害牌",
  ["@@steam__zhengjian-turn"] = "被正谏",
}

local steam__quanlue = fk.CreateTriggerSkill{
  name = "steam__quanlue",
  events = {fk.CardUseFinished},
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and data.card:isCommonTrick() and data.damageDealt then
      return player:getHandcardNum() < 5
    end
  end,
  on_use = function(self, event, target, player, data)
    local n = 0
    for _, num in pairs(data.damageDealt) do
      n = n + 1
    end
    n = math.min(n, 5) - player:getHandcardNum()
    if n > 0 then
      player:drawCards(n, self.name)
    end
  end,
}
tianfeng:addSkill(steam__quanlue)

Fk:loadTranslationTable{
  ["steam__quanlue"] = "权略",
  [":steam__quanlue"] = "锁定技，造成伤害的普通锦囊牌结算后，你将手牌摸至X张（X为此结算中受到伤害的角色数，至多为5）。",
}

local lusu = General(extension, "steam__lusu", "wu", 3)

Fk:loadTranslationTable{
  ["steam__lusu"] = "鲁肃",
  ["#steam__lusu"] = "文韬武略",
  ["illustrator:steam__lusu"] = "",
  ["designer:steam__lusu"] = "颜渊＆江雪埋骨",
}

local steam__taolue = fk.CreateActiveSkill{
  name = "steam__taolue",
  anim_type = "switch",
  switch_skill_name = "steam__taolue",
  min_target_num = 1,
  prompt = function (self)
    return "#steam__taolue-"..Self:getSwitchSkillState(self.name, false, true)
  end,
  card_filter = function(self, to_select, selected)
    if Self:prohibitDiscard(Fk:getCardById(to_select)) then return false end
    if Self:getSwitchSkillState(self.name) == fk.SwitchYang then
      return #selected < 1
    else
      return #selected < 2
    end
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    local to = Fk:currentRoom():getPlayerById(to_select)
    if Self:getSwitchSkillState(self.name) == fk.SwitchYang then
      if #selected_cards ~= 1 then return false end
      local card = Fk:cloneCard("diversion")
      card:addSubcards(selected_cards)
      card.skillName = self.name
      local max_target_num = card.skill:getMaxTargetNum(Self, card)
      return not Self:prohibitUse(card) and not Self:isProhibited(to, card) and #selected < max_target_num
      and card.skill:modTargetFilter(to.id, selected, Self, card, true)
    else
      if #selected_cards ~= 2 then return false end
      local card = Fk:cloneCard("bogus_flower")
      card:addSubcards(selected_cards)
      card.skillName = self.name
      return not to:prohibitUse(card) and not to:isProhibited(to, card)
    end
  end,
  can_use = function(self, player)
    return not (player:getSwitchSkillState(self.name) == fk.SwitchYin and player:getMark("steam__taolue_yinfail-round") ~= 0)
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:throwCard(effect.cards, self.name, player, player)
    if player:getSwitchSkillState(self.name, true) == fk.SwitchYang then
      if not player.dead then
        room:useVirtualCard("diversion", nil, player, table.map(effect.tos, Util.Id2PlayerMapper), self.name)
      end
    else
      local to = room:getPlayerById(effect.tos[1])
      if not to.dead then
        room:useVirtualCard("bogus_flower", nil, to, to, self.name)
        if to == player then
          room:setPlayerMark(player, "steam__taolue_yinfail-round", 1)
        end
      end
    end
  end,
}
lusu:addSkill(steam__taolue)

Fk:loadTranslationTable{
  ["steam__taolue"] = "韬略",
  [":steam__taolue"] = "转换技，出牌阶段，①你可以弃置一张牌并视为使用一张【声东击西】。②你可以弃置两张牌并令一名角色视为使用一张【树上开花】（若选择你，本轮该转换项失效）。",
  ["#steam__taolue-yang"] = "韬略：弃置一张牌并视为使用一张【声东击西】",
  ["#steam__taolue-yin"] = "韬略：弃置两张牌并令一名角色视为使用一张【树上开花】",
}

local steam__hezong = fk.CreateTriggerSkill{
  name = "steam__hezong",
  anim_type = "control",
  frequency = Skill.Compulsory,
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and data.extra_data and data.extra_data.steam__hezong_tos
  end,
  on_cost = function (self, event, target, player, data)
    self.cost_data = {tos = data.extra_data.steam__hezong_tos}
    return true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local tos = table.map(data.extra_data.steam__hezong_tos, Util.Id2PlayerMapper)
    local from, to = tos[1], tos[2]
    if from.dead or to.dead then return end
    if to:getHandcardNum() > from:getHandcardNum() then
      from, to = to, from
    end
    local x = (from:getHandcardNum() - to:getHandcardNum() + 1) // 2
    if x == 0 then return end
    if from ~= player then
      local cards = room:askForCard(from, x, x, false, self.name, false, nil, "#steam__hezong-givehand::"..player.id..":"..x)
      room:obtainCard(player, cards, false, fk.ReasonGive, from.id, self.name)
    end
    if player.dead or to.dead or player:isNude() or to == player then return end
    x = math.min(x, #player:getCardIds("he"))
    room:doIndicate(player.id, {to.id})
    room:delay(200)
    local cards = room:askForCard(player, x, x, true, self.name, false, nil, "#steam__hezong-give::"..to.id..":"..x)
    room:obtainCard(to, cards, false, fk.ReasonGive, player.id, self.name)
  end,

  refresh_events = {fk.CardUseFinished},
  can_refresh = function(self, event, target, player, data)
    return player:hasSkill(self, true) and table.contains(data.card.skillNames, "steam__taolue")
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local tos = TargetGroup:getRealTargets(data.tos)
    if #tos > 0 then
      local old = player:getMark("steam__hezong_to-turn")
      local new = tos[1]
      room:setPlayerMark(player, "@steam__hezong-turn", room:getPlayerById(new).general)
      room:setPlayerMark(player, "steam__hezong_to-turn", new)
      if old ~= 0 and old ~= new then
        data.extra_data = data.extra_data or {}
        data.extra_data.steam__hezong_tos = {new, old}
      end
    end
  end,

  on_lose = function (self, player, is_death)
    player.room:setPlayerMark(player, "@steam__hezong-turn", 0)
  end,
}
lusu:addSkill(steam__hezong)

Fk:loadTranslationTable{
  ["steam__hezong"] = "合纵",
  [":steam__hezong"] = "锁定技，因“韬略”使用的牌结算后，若目标角色与本回合上一次指定的不同，你令手牌数较多的一方将X张手牌交给你，然后你将等量张牌交给另一方（X为双方手牌数差值的一半，向上取整）。",
  ["@steam__hezong-turn"] = "合纵",
  ["#steam__hezong-givehand"] = "合纵：请将 %arg 张手牌交给 %dest",
  ["#steam__hezong-give"] = "合纵：请将 %arg 张牌交给 %dest",
}

local kobe = General(extension, "steam__kobe", "west", 4)
Fk:loadTranslationTable{
  ["steam__kobe"] = "科比", -- Kobe Bryant
  ["#steam__kobe"] = "燃蟒化蛟",
  ["illustrator:steam__kobe"] = "",
  ["designer:steam__kobe"] = "杨林",
  ["~steam__kobe"] = "man，hhhhh，what can I say,mamba out.",
}

local steam__zhijin = fk.CreateTriggerSkill{
  name = "steam__zhijin",
  anim_type = "control",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    local room = player.room
    local ids = {}
    for _, move in ipairs(data) do
      if move.toArea == Card.DiscardPile and move.moveReason == fk.ReasonUse then
        for _, info in ipairs(move.moveInfo) do
          if room:getCardArea(info.cardId) == Card.DiscardPile then
            table.insert(ids, info.cardId)
          end
        end
      end
    end
    if #ids == 0 then return false end
    ids = U.moveCardsHoldingAreaCheck(room, ids)
    if #ids == 0 then return false end
    local useEvent = room.logic:getCurrentEvent().parent
    if not useEvent then return false end
    if useEvent.event == GameEvent.UseCard then
      -- 延时锦囊并不会触发这个事件
      local get = useEvent.data[1].from ~= player.id
      if #useEvent:searchEvents(GameEvent.CardEffect, 1, function(e)
        local effect = e.data[1]
        return effect.isCancellOut and e.parent == useEvent
      end) > 0 then
        self.cost_data = {cards = ids, get = get}
        return true
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local targets = table.filter(room.alive_players, function (p)
      return player:canPindian(p, true)
    end)
    if #targets == 0 then return false end
    local ids = self.cost_data.cards
    local tos, cards = room:askForChooseCardsAndPlayers(player, 1, 1, table.map(targets, Util.IdMapper), 1, 1,
    tostring(Exppattern{ id = ids }), "#steam__zhijin-choose", self.name, true, nil, nil, {expand_pile = ids})
    if #tos > 0 then
      self.cost_data.tos = tos
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    local fromCardId = self.cost_data.cards[1]
    local willGet = self.cost_data.get
    room:delay(200)
    local pindian = player:pindian({to}, self.name, Fk:getCardById(fromCardId))
    if not player.dead then
      local win = pindian.results[to.id].winner == player
      local get = {}
      if win then
        local toCardId = pindian.results[to.id].toCard:getEffectiveId()
        if toCardId and room:getCardArea(toCardId) == Card.DiscardPile then
          table.insert(get, toCardId)
        end
      end
      if willGet and room:getCardArea(fromCardId) == Card.DiscardPile then
        table.insert(get, fromCardId)
      end
      if #get > 0 then
        room:delay(200)
        room:obtainCard(player, get, true, fk.ReasonJustMove, player.id, self.name)
      end
      if not win and not to.dead then
        room:damage { from = player, to = to, damage = 1, skillName = self.name }
        room:invalidateSkill(player, self.name, "-round")
      end
    end
  end,
}
kobe:addSkill(steam__zhijin)


local steam__yigui = fk.CreateTriggerSkill{
  name = "steam__yigui",
  anim_type = "big",
  frequency = Skill.Compulsory,
  events = {fk.Deathed},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self, false, true) and target and target.id == player.tag["steam__yigui_killer"]
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    room:setPlayerMark(player, "@steam__yigui", 0)
    player.tag["steam__yigui_killer"] = 0
    room:setPlayerRest(player, 0)
    room:revivePlayer(player, true, self.name)
    room:setPlayerProperty(player, "hp", math.min(2, player.maxHp))
    player:drawCards(4, self.name)
  end,

  refresh_events = {fk.Deathed},
  can_refresh = function (self, event, target, player, data)
    return target == player and player:hasShownSkill(self, false, true) and player.rest == 0
    and data.damage and data.damage.from and data.damage.from ~= player
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:setPlayerMark(player, "@steam__yigui", data.damage.from.general)
    player.tag["steam__yigui_killer"] = data.damage.from.id
  end,

  on_lose = function (self, player, is_death)
    if not is_death and player:getMark("@steam__yigui") ~= 0 then
      player.room:setPlayerMark(player, "@steam__yigui", 0)
    end
  end,
}
kobe:addSkill(steam__yigui)

Fk:loadTranslationTable{
  ["steam__zhijin"] = "执进",
  -- 当一张牌因使用而置入弃牌堆时，若此牌被抵消过
  [":steam__zhijin"] = "一张即时牌被抵消而置入弃牌堆时，你可用此牌与一名其他角色拼点；若你拼点赢/此牌的使用者不为你，你获得对方的拼点牌/你的拼点牌。若你没赢，你对该角色造成一点伤害，然后此技能在本轮失效。",
  ["#steam__zhijin-choose"] = "执进：你可用此牌与一名其他角色拼点",

  ["$steam__zhijin1"] = "I had a purpose.I wanted to be one of the best basketball players to ever play.and anything else that was outside of that lane，I didn’t have time for.",
  ["$steam__zhijin2"] = "My brain cannot process failure.It will not process failure.",

  ["steam__yigui"] = "忆归",
  [":steam__yigui"] = "锁定技，杀死你的其他角色阵亡后，你复活，并将体力值回复至两点，再摸四张牌。",
  ["@steam__yigui"] = "忆归",

  ["$steam__yigui1"] = "see you again.",
  ["$steam__yigui2"] = "If I accept there and have to face myself and tell myself you're a failure, I think that's a worse, that's almost worse than death.",
}

local steam__yuanshu = General(extension, "steam__yuanshu", "qun", 4)

local steam_yongsi = fk.CreateTriggerSkill{
  name = "steam_yongsi",
  events = {fk.TurnStart,fk.AskForCardUse,fk.AskForPeaches},
  anim_type = "drawcard",
  can_trigger = function (self, event, target, player, data)
    if event == fk.TurnStart then
      return player:hasSkill(self) and target == player
    elseif event == fk.AskForCardUse then
      return player:hasSkill(self) and target == player and data.cardName == "jink"
    else
      return player:hasSkill(self) and player.phase == Player.NotActive and target == player
    end
  end,
  on_cost = function (self, event, target, player, data)
    local reject = player:getTableMark("@steam_yongsi_mark")
    if event == fk.TurnStart then
      return table.contains(reject,"#yongsi_play") or player.room:askForSkillInvoke(player,self.name,nil,"#yongsi-rejectPlay")
    elseif event == fk.AskForCardUse then
      return table.contains(reject,"#yongsi_jink") or player.room:askForSkillInvoke(player,self.name,nil,"#yongsi-rejectJink")
    else
      return table.contains(reject,"#yongsi_peach") or player.room:askForSkillInvoke(player,self.name,nil,"#yongsi-rejectPeach")
    end
    
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local is_maxHandCard = table.every(room:getOtherPlayers(player),function (element, index, array)
      return player:getHandcardNum()>element:getHandcardNum()
    end) 
    room:drawCards(player,3)
    if player.dead then return end
    local become_maxHandCard = (not is_maxHandCard) and table.every(room:getOtherPlayers(player),function (element, index, array)
      return player:getHandcardNum()>element:getHandcardNum()
    end) 
    local reject = player:getTableMark("@steam_yongsi_mark")
    if event == fk.TurnStart then
      if (not table.contains(reject,"#yongsi_play")) and become_maxHandCard then
        room:addTableMark(player,"@steam_yongsi_mark","#yongsi_play")
      end
      room.logic:breakTurn()
      return true
    elseif event == fk.AskForCardUse then
      room:addPlayerMark(player,"cant_use_jink")
      local evt = room.logic:getCurrentEvent():findParent(GameEvent.CardEffect) or room.logic:getCurrentEvent():findParent(GameEvent.SkillEffect)
      if evt then
        evt:addCleaner(function (self)
          room:setPlayerMark(player,"cant_use_jink",0)
        end)
      end
      if (not table.contains(reject,"#yongsi_jink")) and become_maxHandCard then
        room:addTableMark(player,"@steam_yongsi_mark","#yongsi_jink")
      end
    else
      room:setPlayerMark(player,"cant_use_peach",1)
      if  (not table.contains(reject,"#yongsi_peach")) and become_maxHandCard then
        room:addTableMark(player,"@steam_yongsi_mark","#yongsi_peach")
      end
    end
  end,
  refresh_events = {fk.AskForPeachesDone},
  can_refresh = function (self, event, target, player, data)
    return player:hasSkill(self)
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:setPlayerMark(player,"cant_use_peach",0)
  end
}
local steam_yongsi_prohibit = fk.CreateProhibitSkill{
  name = "#steam_yongsi_prohibit",
  prohibit_use = function(self, player, card)
    return (player:getMark("cant_use_jink")>0 and card.trueName == "jink") or(player:getMark("cant_use_peach")>0 and card.trueName == "peach")
  end,
}
steam_yongsi:addRelatedSkill(steam_yongsi_prohibit)
steam__yuanshu:addSkill(steam_yongsi)

local steam_pizhi = fk.CreateTriggerSkill{
  name = "steam_pizhi",
  events = {fk.TargetConfirmed},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and player == target and data.card.trueName == "slash"
  end,
  on_cost = function (self, event, target, player, data)
    local cards = player.room:askForDiscard(player,1,2,true,self.name,true,".","pizhi-discard",true)
    self.cost_data = cards;
    return #cards>0
  end,
  on_use = function (self, event, target, player, data)
    player.room:throwCard(self.cost_data,self.name,player)
    if player.dead then return end
    player.room:addPlayerMark(player,"pizhi-extra",#self.cost_data)
    data.additionalEffect = (data.additionalEffect or 0) + player:getMark("pizhi-extra");
  end
}
local steam_pizhi_delay = fk.CreateTriggerSkill{
  name = "#steam_pizhi_delay",
  events = {fk.CardUseFinished},
  mute = true,
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and player:getMark("pizhi-extra")>0 and data.card.trueName == "slash"
  end,
  on_trigger = function (self, event, target, player, data)
    local cardUser = player.room:getPlayerById(data.from)
    if player:getMark("pizhi-extra")>0 then
      while player:getMark("pizhi-extra")>0 do
        player.room:removePlayerMark(player,"pizhi-extra")
        if #cardUser:getCardIds("hej")>0 and cardUser:isAlive() then
          player.room:useVirtualCard("dismantlement",nil,player,{cardUser})
        else
          break
        end
        if player.dead then return end
      end
    end
  end
}

steam_pizhi:addRelatedSkill(steam_pizhi_delay)
steam__yuanshu:addSkill(steam_pizhi)

Fk:loadTranslationTable {
  ["steam__yuanshu"] = "袁术",
  ["#steam__yuanshu"] = "蠹殁安还",
  ["designer:steam__yuanshu"] = "牧孖",
  ["steam_yongsi_jink"] = "庸肆",
  ["steam_yongsi"] = "庸肆",
  [":steam_yongsi"] = "回合开始时，或当你需要使用【闪】时，或当你于回合外需要使用【桃】时，你可以拒绝执行之并摸三张牌，"..
    "然后若你手牌数变为全场唯一最多，你于该时机仅能如此做。",
  ["#yongsi-rejectPeach"] = "庸肆：你可以拒绝使用【桃】并摸三张牌，若手牌变为最多则此后你只能此做",
  ["#yongsi-rejectJink"] = "庸肆：你可以拒绝使用【闪】并摸三张牌，若手牌变为最多则此后你只能此做",
  ["#yongsi-rejectPlay"] = "庸肆：你可以摸三张牌并跳过本回合，若手牌变为最多则此后你只能此做",
  ["#steam_yongsi_prohibit"] = "庸肆",
  ["@steam_yongsi_mark"] = "庸肆",
  ["#yongsi_play"] = "出",
  ["#yongsi_jink"] = "闪",
  ["#yongsi_peach"] = "桃",
  ["steam_pizhi"] = "圮秩",
  [":steam_pizhi"] = "当你成为【杀】的目标后，你可以弃置至多两张牌令此牌对你结算等量次，则此牌结算结束后，你视为对其使用等量张【过河拆桥】。",
  ["pizhi-discard"] = "圮秩：你可以弃牌使此【杀】牌对你额外结算等量次"
}



local steam__zhengxuan = General(extension, "steam__zhengxuan", "qun", 3)

local steam__botong = fk.CreateTriggerSkill{
  name = "steam__botong",
  events = {fk.CardUsing, fk.TurnStart},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return end
    if event == fk.CardUsing then
      if player.phase ~= Player.NotActive then return end
      local currentEvent = player.room.logic:getCurrentEvent():findParent(GameEvent.UseCard, true)
      if currentEvent then
        local last = player.room.logic:getEventsByRule(GameEvent.UseCard, 1, function (e)
          return e.id < currentEvent.id
        end, 1)
        return #last > 0 and last[1].data[1].from ~= target.id
      end
    else
      return target == player and player:getMark("@hf_classic") > 1
    end
  end,
  on_cost = function (self, event, target, player, data)
    return event == fk.CardUsing or player.room:askForSkillInvoke(player, self.name)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.CardUsing then
      room:notifySkillInvoked(player, self.name, "special")
      room:addPlayerMark(player, "@hf_classic")
    else
      room:notifySkillInvoked(player, self.name, "drawcard")
      player:broadcastSkillInvoke(self.name, 1)
      local top = room:getNCards(player:getMark("@hf_classic"))
      room:setPlayerMark(player, "@hf_classic", 0)
      local result = room:askForCustomDialog(player, self.name,
      "packages/aaa_steam/qml/BotongBox.qml", {
        top, "#steam__botong"})
      if result == "" then return end
      local cards = json.decode(result)
      if #cards == 0 then return end
      player:broadcastSkillInvoke(self.name, 2)
      room:obtainCard(player, cards, true, fk.ReasonJustMove, player.id, self.name)
      while not player.dead do
        cards = table.filter(cards, function (id) return table.contains(player.player_cards[Player.Hand], id) end)
        if #cards == 0 then break end
        if table.every(room.alive_players, function (p)
          return #p:getPile("steam__botong_pile") > 0
        end) then break end
        local _,dat = room:askForUseActiveSkill(player, "steam__botong_choose", "#steam__botong-put", true, {steam__botong_cards = cards})
        if not dat then break end
        room:getPlayerById(dat.targets[1]):addToPile("steam__botong_pile", dat.cards, true, self.name, player.id)
      end
    end
  end,
}

local steam__botong_delay = fk.CreateTriggerSkill{
  name = "#steam__botong_delay",
  anim_type = "support",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    return target == player and player.phase == Player.Start and #player:getPile("steam__botong_pile") > 0
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local suit = Fk:getCardById(player:getPile("steam__botong_pile")[1]).suit
    room:obtainCard(player, player:getPile("steam__botong_pile"), true, fk.ReasonJustMove)
    if player.dead then return end
    if suit == Card.Heart then
      target:gainAnExtraPhase(Player.Play, true)
    elseif suit == Card.Club then
      target:gainAnExtraPhase(Player.Draw, true)
    elseif suit == Card.Diamond then
      room:recover { num = 1, skillName = self.name, who = player, recoverBy = player }
    elseif suit == Card.Spade then
      target:skip(Player.Judge)
      target:skip(Player.Discard)
    end
  end,
}
steam__botong:addRelatedSkill(steam__botong_delay)

steam__zhengxuan:addSkill(steam__botong)

local steam__botong_choose = fk.CreateActiveSkill{
  name = "steam__botong_choose",
  card_num = 1,
  target_num = 1,
  card_filter = function(self, to_select, selected)
    return #selected == 0 and table.contains(self.steam__botong_cards or {}, to_select)
    and Fk:getCardById(to_select).suit ~= Card.NoSuit
  end,
  target_filter = function(self, to_select, selected, selected_cards)
    local to = Fk:currentRoom():getPlayerById(to_select)
    return #selected == 0 and #selected_cards == 1 and to and #to:getPile("steam__botong_pile") == 0
  end,
}
Fk:addSkill(steam__botong_choose)

local steam__yinxiu = fk.CreateTriggerSkill{
  name = "steam__yinxiu",
  anim_type = "defensive",
  frequency = Skill.Compulsory,
  events = {fk.DamageInflicted, fk.PreCardEffect},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      if event == fk.PreCardEffect then
        return player.id == data.to and (data.card:isVirtual() or data.card.name ~= Fk:getCardById(data.card.id, true).name)
      else
        return ((not data.card) or (not data.from)) and target == player
      end
    end
  end,
  on_use = Util.TrueFunc,
}
steam__zhengxuan:addSkill(steam__yinxiu)

Fk:loadTranslationTable{
  ["steam__zhengxuan"] = "郑玄",
  ["#steam__zhengxuan"] = "为世儒宗",
  ["cv:steam__zhengxuan"] = "官方",
  ["designer:steam__zhengxuan"] = "emo公主",
  ["illustrator:steam__zhengxuan"] = "官方",

  ["steam__botong"] = "博通",
  [":steam__botong"] = "你的回合外，每当一名角色使用牌时，若其与上一张牌的使用者不同，你获得1枚“经”。回合开始时，你可以移去所有“经”（至少2枚）进行一次“采经”。然后你可以将获得的牌扣置于任意角色武将牌旁（每角色限一张），其下个准备阶段获得之，并按照花色获得效果："..
  "<br><font color='red'>♥</font>，获得一个出牌阶段；♣，获得一个摸牌阶段；"..
  "<br><font color='red'>♦</font>，回复一点体力；♠，跳过判定和弃牌阶段。"..
  "<br><font color='grey'><b>#采经：</b>将牌堆顶X张牌随机打乱，整理这些牌，将其中角度相同的明牌与暗牌挪动到一起消除，获得消除的牌（X为移去“经”数）。</font>",
  ["#steam__botong"] = "“采经”：将角度相同的明牌和暗牌移动到一起消除",
  ["@hf_classic"] = "经",
  ["#steam__botong_delay"] = "博通",
  ["steam__botong_pile"] = "博通",
  ["steam__botong_choose"] = "博通",
  ["#steam__botong-put"] = "博通：你可将“采经”牌扣置于任意角色武将牌旁，其下个准备阶段获得并根据花色执行效果",

  ["steam__yinxiu"] = "隐修",
  [":steam__yinxiu"] = "锁定技，虚拟牌或转化牌对你无效，防止你受到无来源或无伤害牌造成的伤害。",

  ["$steam__botong1"] = "举吾一家之见，其反诸位之解。",
  ["$steam__botong2"] = "此经已著毕，汝可视观之。",
  ["~steam__zhengxuan"] = "学海无涯，憾吾生，有涯矣……",
}

local sunyi = General(extension, "steam__sunyi", "wu", 5)

local steam__jiqiao = fk.CreateTriggerSkill{
  name = "steam__jiqiao",
  events = {fk.CardUseFinished, fk.EventPhaseStart},
  anim_type = "control",
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target == player then
      if event == fk.CardUseFinished then
        return true
      else
        return player.phase == Player.Finish and player.maxHp ~= (player:getMark("@steam__jiqiao") + 1)
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    if event == fk.CardUseFinished then return true end
    return player.room:askForSkillInvoke(player, self.name, nil, "#steam__jiqiao-invoke:::"..(player:getMark("@steam__jiqiao") + 1))
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.CardUseFinished then
      room:addPlayerMark(player, "@steam__jiqiao")
    else
      room:changeMaxHp(player, player:getMark("@steam__jiqiao") + 1 - player.maxHp)
      room:setPlayerMark(player, "@steam__jiqiao", 0)
    end
  end,
}
sunyi:addSkill(steam__jiqiao)

local steam__weizhong = fk.CreateTriggerSkill{
  name = "steam__weizhong",
  events = {fk.MaxHpChanged},
  frequency = Skill.Compulsory,
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target == player and data.num ~= 0
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if data.num < 0 then
      player:broadcastSkillInvoke(self.name, 2)
      room:notifySkillInvoked(player, self.name, "drawcard")
      player:drawCards(2, self.name)
    else
      player:broadcastSkillInvoke(self.name, 1)
      room:notifySkillInvoked(player, self.name, "offensive")
      for i = 1, 2 do
        local tos = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1,
        "#steam__weizhong-damage:::"..i, self.name, false)
        if #tos > 0 then
          room:damage { from = player, to = room:getPlayerById(tos[1]), damage = 1, skillName = self.name }
        end
      end
    end
  end,
}
sunyi:addSkill(steam__weizhong)

Fk:loadTranslationTable{
  ["steam__sunyi"] = "孙翊",
  ["#steam__sunyi"] = "翻江龙",
  ["designer:steam__sunyi"] = "未折",
  ["illustrator:steam__sunyi"] = "",

  ["steam__jiqiao"] = "激峭",
  [":steam__jiqiao"] = "你使用牌后，获得一枚“峭”。结束阶段，你可以将体力上限调整至“峭”数加一，并清除全部“峭”。",
  ["@steam__jiqiao"] = "峭",
  ["#steam__jiqiao-invoke"] = "激峭：你可以将体力上限调整为 %arg 并清除“峭”标记",
  
  ["steam__weizhong"] = "威重",
  [":steam__weizhong"] = "锁定技，当你的体力上限减少/增加时，你摸两张牌/分配两点伤害。",
  ["#steam__weizhong-damage"] = "威重：请分配1点伤害！（第%arg点，共2点）",

  ["$steam__jiqiao1"] = "我自饮马长江头，横刀问天谁敌手！",
  ["$steam__jiqiao2"] = "诸君且拭目，看我江东子弟虎步南北、纵横天下！",
  ["$steam__weizhong1"] = "父魂于身，兄姿于表，天下自可纵横！",
  ["$steam__weizhong2"] = "擎旗斩将学霸王，秣马厉兵效乌程！",
}

local xunyu = General(extension, "steam__xunyu", "wei", 3)
Fk:loadTranslationTable{
  ["steam__xunyu"] = "荀彧",
  ["#steam__xunyu"] = "怀忠念治",
  ["designer:steam__xunyu"] = "o.O",
  ["illustrator:steam__xunyu"] = "徐子晖",
  ["~steam__xunyu"] = "大江东去，当年月照今世人。",
}

local steam__kuangyi = fk.CreateTriggerSkill{
  name = "steam__kuangyi",
  anim_type = "support",
  frequency = Skill.Compulsory,
  events = {fk.Damaged},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local card = Fk:cloneCard("reinforcement")
    card.skillName = self.name
    if player:prohibitUse(card) then return end
    local max_target_num = card.skill:getMaxTargetNum(player, card)
    local targets = table.map(table.filter(room.alive_players, function (p) return not player:isProhibited(p, card) end), Util.IdMapper)
    if #targets == 0 or max_target_num == 0 then return end
    local tos = room:askForChoosePlayers(player, targets, 1, max_target_num, "#steam__kuangyi-choose:"..target.id, self.name, false)
    room:sortPlayersByAction(tos)
    room:useCard{
      from = player.id,
      tos = table.map(tos, function(p) return {p} end),
      card = card,
    }
    if (target == player) == (table.contains(tos, player.id)) then
      room:invalidateSkill(player, self.name, "-round")
    end
  end,
}

xunyu:addSkill(steam__kuangyi)

Fk:loadTranslationTable{
  ["steam__kuangyi"] = "匡翊",
  [":steam__kuangyi"] = "锁定技，当一名角色受到伤害后，你视为使用一张【增兵减灶】，若受伤角色和目标角色均为你或均不为你，本轮“匡翊”失效。",
  ["#steam__kuangyi-choose"] = "匡翊：%src 受到伤害，你须选择【增兵减灶】的目标并使用之",

  ["$steam__kuangyi1"] = "家国兴衰，系于一肩之上，朝纲待重振之时。",
  ["$steam__kuangyi2"] = "吾辈向汉，当矢志不渝，不可坐视神州陆沉。",
}

local steam__anshu = fk.CreateTriggerSkill{
  name = "steam__anshu",
  anim_type = "support",
  frequency = Skill.Compulsory,
  events = {fk.CardUseFinished},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) then
      return player:getHandcardNum() > 3 and player.phase ~= Player.NotActive and U.IsUsingHandcard(player, data)
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = player:getCardIds("h")
    if #cards > 4 then
      cards = room:askForCard(player, 4, 9999, false, self.name, false, nil, "#steam__anshu-card")
    end
    cards = room:askForGuanxing(player, cards, {#cards, #cards}, {0,0}, self.name, true).top
    room:moveCardTo(table.reverse(cards), Card.DrawPile, nil, fk.ReasonPut, self.name, nil, false, player.id)
    if player.dead then return end
    local card = Fk:cloneCard("amazing_grace")
    card.skillName = self.name
    if player:prohibitUse(card) then return end
    local tos = table.map(table.filter(room.alive_players, function (p) return not player:isProhibited(p, card) end), Util.IdMapper)
    if #tos == 0 then return end
    local first = room:askForChoosePlayers(player, tos, 1, 1, "#steam__anshu-begin", self.name, false)[1]
    room:useCard{
      from = player.id,
      tos = table.map(tos, function(p) return {p} end),
      card = card,
      extra_data = {steam__anshu_beginner = first}
    }
  end,

  refresh_events = {fk.BeforeCardUseEffect},
  can_refresh = function(self, event, target, player, data)
    return data.card.trueName == "amazing_grace" and table.contains(data.card.skillNames, self.name)
    and data.extra_data and data.extra_data.steam__anshu_beginner
  end,
  on_refresh = function(self, event, target, player, data)
    local orig_tos, tos, first = TargetGroup:getRealTargets(data.tos), {}, player.room:getPlayerById(data.extra_data.steam__anshu_beginner)
    local temp = first
    repeat
      if table.contains(orig_tos, temp.id) then
        table.insert(tos, {temp.id})
      end
      temp = temp.next
    until temp == first
    data.tos = tos
  end,
}
xunyu:addSkill(steam__anshu)

Fk:loadTranslationTable{
  ["steam__anshu"] = "安庶",
  [":steam__anshu"] = "锁定技，当你于回合内使用手牌后，你将至少四张手牌置于牌堆顶并视为使用一张由你选择起始结算角色的【五谷丰登】。",
  ["#steam__anshu-card"] = "安庶：请将至少四张手牌置于牌堆顶",
  ["#steam__anshu-begin"] = "安庶：选择一名角色作为【五谷丰登】的起始结算角色",
  
  ["$steam__anshu1"] = "老幼有所养，天下皆享太平之福。",
  ["$steam__anshu2"] = "民有所食，此诚古贤所言之盛世。",
}

local nvwa = General(extension, "steam__nvwa", "god", 3, 3, General.Female)
nvwa.hidden = true
Fk:loadTranslationTable{
  ["steam__nvwa"] = "女娲",
  ["#steam__nvwa"] = "阴皇",
  ["designer:steam__nvwa"] = "杨林",
  ["illustrator:steam__nvwa"] = "AI",
}

local steam__bushi = fk.CreateTriggerSkill{
  name = "steam__bushi",
  events = {fk.CardUseFinished},
  anim_type = "drawcard",
  can_trigger = function(self, event, target, player, data)
    if player == target and player:hasSkill(self) then
      return table.find({1,2,3}, function (num)
        return #player:getCardIds("he") >= num and not table.contains(player:getTableMark(self.name), num)
      end)
    end
  end,
  on_cost = function (self, event, target, player, data)
    local _, dat = player.room:askForUseActiveSkill(player, "steam__bushi_active", "#steam__bushi-card:::"..data.card:toLogString(),
    true, {steam__bushi_info = {suit = data.card.suit, type = data.card.type, color = data.card.color} } )
    if dat then
      self.cost_data = {cards = dat.cards}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = self.cost_data.cards
    local num = #cards
    room:addTableMark(player, self.name, num)
    room:recastCard(cards, player, self.name)
    if not player.dead then
      player:drawCards(num, self.name)
    end
  end,

  refresh_events = {fk.AfterDrawPileShuffle, fk.AfterRoundEnd, fk.AfterTurnEnd},
  can_refresh = function(self, event, target, player, data)
    return player:hasSkill(self, true)
  end,
  on_refresh = function (self, event, target, player, data)
    local map = {[fk.AfterDrawPileShuffle] = 3, [fk.AfterRoundEnd] = 2, [fk.AfterTurnEnd] = 1}
    player.room:removeTableMark(player, self.name, map[event])
  end,
}

local steam__bushi_active = fk.CreateActiveSkill{
  name = "steam__bushi_active",
  interaction = function(self)
    local all_choices, choices = {}, {}
    for i = 1, 3 do
      local c = "steam__bushi"..i
      table.insert(all_choices, c)
      if not table.contains(Self:getTableMark("steam__bushi"), i) then
        table.insert(choices, c)
      end
    end
    if #choices > 0 then
      return UI.ComboBox { choices = choices, all_choices = all_choices }
    end
  end,
  card_filter = function(self, to_select, selected)
    local choice = self.interaction.data
    if choice and self.steam__bushi_info then
      local num = tonumber(choice:sub(-1, -1))
      if #selected < num then
        if num == 1 then
          return Fk:getCardById(to_select).color ~= self.steam__bushi_info.color
        end
        local all, ret = {to_select}, {}
        table.insertTable(all, selected)
        if num == 2 then
          for _, id in ipairs(all) do
            table.insertIfNeed(ret, Fk:getCardById(id).type)
          end
          table.insertIfNeed(ret, self.steam__bushi_info.type)
        else
          for _, id in ipairs(all) do
            table.insertIfNeed(ret, Fk:getCardById(id).suit)
          end
          table.insertIfNeed(ret, self.steam__bushi_info.suit)
        end
        return #ret == (#all + 1)
      end
    end
  end,
  target_filter = Util.FalseFunc,
  feasible = function(self, selected, selected_cards)
    local choice = self.interaction.data
    return choice and #selected_cards == tonumber(choice:sub(-1, -1))
  end,
}
Fk:addSkill(steam__bushi_active)

nvwa:addSkill(steam__bushi)

Fk:loadTranslationTable{
  ["steam__bushi"] = "补世",
  [":steam__bushi"] = "你使用一张牌后，你可重铸三/二/一张花色/类别/颜色均不同且与使用牌不同的牌，再摸等量张牌；然后你不能因此重铸相等张数的牌，直到牌堆洗切/本轮结束/本回合结束。",
  ["steam__bushi_active"] = "补世",
  ["#steam__bushi-card"] = "补世：你可重铸三/二/一张与%arg花色/类别/颜色均不同的牌，再摸等量张牌",
  ["steam__bushi1"] = "1张颜色不同的牌",
  ["steam__bushi2"] = "2张类别不同的牌",
  ["steam__bushi3"] = "3张花色不同的牌",
}

local steam__zhuren = fk.CreateActiveSkill{
  name = "steam__zhuren",
  anim_type = "control",
  card_num = 0,
  target_num = 1,
  prompt = "#steam__zhuren",
  card_filter = Util.FalseFunc,
  target_tip = function (self, to_select, selected, selected_cards, card, selectable, extra_data)
    if #selected == 0 then
      local to = Fk:currentRoom():getPlayerById(to_select)
      if table.contains(Self:getTableMark("steam__zhuren_forbid"), to.id) then
        return "@@steam__zhuren_forbid"
      end
    end
  end,
  target_filter = function(self, to_select, selected)
    local to = Fk:currentRoom():getPlayerById(to_select)
    return #selected == 0 and not to:isKongcheng() and math.abs(Self:getHandcardNum() - to:getHandcardNum()) == 1
    and not table.contains(Self:getTableMark("steam__zhuren_forbid"), to.id)
  end,
  can_use = function(self, player)
    return true
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local to = room:getPlayerById(effect.tos[1])
    if to:isKongcheng() then return end
    local cid = room:askForCardChosen(player, to, "h", self.name)
    room:throwCard(cid, self.name, to, player)
    if player.dead or to.dead then return end
    room:addTableMark(player, "steam__zhuren_forbid", to.id)
  end,

  on_lose = function (self, player)
    player.room:setPlayerMark(player, "steam__zhuren_forbid", 0)
  end,
}

local steam__zhuren_trigger = fk.CreateTriggerSkill{
  name = "#steam__zhuren_trigger",
  refresh_events = {fk.AfterCardsMove},
  can_refresh = function(self, event, target, player, data)
    return #player:getTableMark("steam__zhuren_forbid") ~= 0
  end,
  on_refresh = function (self, event, target, player, data)
    local mark = player:getTableMark("steam__zhuren_forbid")
    for _, move in ipairs(data) do
      if move.from and move.from ~= player.id and
      table.find(move.moveInfo, function (info) return info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip end) then
        table.removeOne(mark, move.from)
      end
    end
    player.room:setPlayerMark(player, "steam__zhuren_forbid", #mark > 0 and mark or 0)
  end,
}

steam__zhuren:addRelatedSkill(steam__zhuren_trigger)

nvwa:addSkill(steam__zhuren)

Fk:loadTranslationTable{
  ["steam__zhuren"] = "铸人",
  [":steam__zhuren"] = "出牌阶段，你可以弃置与你手牌数之差为1的一名角色的一张手牌；然后你不能对其发动此技能，直到其失去牌。",
  ["#steam__zhuren"] = "铸人：选择与你手牌数之差为1的一名角色，弃置其一张手牌",
  ["@@steam__zhuren_forbid"] = "禁止选",
}


local zhangyu = General(extension, "steam__zhangyu", "shu", 3)
local chentu = fk.CreateTriggerSkill{
  name = "steam__chentu",
  anim_type = "support",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return target == player and player:hasSkill(self) and
      table.contains({Player.Start, Player.Finish}, player.phase) and
      table.find(player.room.alive_players, function (p)
        return not p:isNude()
      end)
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local targets = table.filter(room:getOtherPlayers(player), function (p)
      return not p:isNude()
    end)
    if table.find(player:getCardIds("he"), function (id)
      return not player:prohibitDiscard(id)
    end) then
      table.insert(targets, player)
    end
    local to = room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 1, "#steam__chentu-choose", self.name, true)
    if #to > 0 then
      self.cost_data = {tos = to}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    local n = #room:askForDiscard(to, 1, 999, true, self.name, false, nil, "#steam__chentu-discard")
    if n == 0 then return end
    local cards = room:getNCards(2 * n)
    room:moveCardTo(cards, Card.Processing, nil, fk.ReasonJustMove, self.name, nil, true, to.id)
    if not player.dead then
      local result = U.askforChooseCardsAndChoice(player, cards, {"OK"}, self.name, "#steam__chentu-swap", {"Cancel"}, 2, 2)
      if #result == 2 then
        local i1, i2 = table.indexOf(cards, result[1]), table.indexOf(cards, result[2])
        cards[i1], cards[i2] = result[2], result[1]
      end
    end
    if not to.dead then
      local result = room:askForPoxi(to, self.name, { { "Top", cards } }, nil, true)
      if #result > 0 then
        room:moveCardTo(result, Card.PlayerHand, to, fk.ReasonJustMove, self.name, nil, true, to.id)
      end
    end
    cards = table.filter(cards, function (id)
      return room:getCardArea(id) == Card.Processing
    end)
    if #cards > 0 then
      cards = table.reverse(cards)
      room:moveCards({
        ids = cards,
        toArea = Card.DrawPile,
        moveReason = fk.ReasonJustMove,
      })
    end
  end,
}
Fk:addPoxiMethod{
  name = "steam__chentu",
  prompt = function (data, extra_data)
    return "#steam__chentu"
  end,
  card_filter = function(to_select, selected, data, extra_data)
    if #selected == 0 then
      return true
    else
      return Fk:getCardById(to_select):compareColorWith(Fk:getCardById(selected[1])) and
        table.find(selected, function (id)
          return table.indexOf(data[1][2], id) + 1 == table.indexOf(data[1][2], to_select) or
            table.indexOf(data[1][2], id) - 1 == table.indexOf(data[1][2], to_select)
        end)
    end
  end,
  feasible = function(selected, data, extra_data)
    return #selected > 0
  end,
}
local kuiming = fk.CreateTriggerSkill{
  name = "steam__kuiming",
  anim_type = "control",
  events = {fk.EventPhaseProceeding},
  can_trigger = function (self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Judge
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    player._phase_end = true
    local cards = {}
    for _ = 1, 100, 1 do
      local judge = {
        who = player,
        reason = self.name,
        pattern = ".|.|^spade",
        skipDrop = true,
      }
      room:judge(judge)
      if judge.card then
        table.insert(cards, judge.card.id)
        if judge.card.suit == Card.Spade then
          break
        end
      end
    end
    cards = table.filter(cards, function (id)
      return room:getCardArea(id) == Card.Processing
    end)
    if #cards == 0 then return end
    if player.dead then
      room:moveCardTo(cards, Card.DiscardPile, nil, fk.ReasonJudge)
    else
      local result = room:askForGuanxing(player, cards, nil, nil, self.name, true, {"Top", "Bottom"})
      local moves = {}
      if #result.top > 0 then
        result.top = table.reverse(result.top)
        table.insert(moves, {
          ids = result.top,
          toArea = Card.DrawPile,
          moveReason = fk.ReasonJustMove,
          skillName = self.name,
          proposer = player.id,
          moveVisible = true,
          drawPilePosition = 1,
        })
      end
      if #result.bottom > 0 then
        table.insert(moves, {
          ids = result.bottom,
          toArea = Card.DrawPile,
          moveReason = fk.ReasonJustMove,
          skillName = self.name,
          proposer = player.id,
          moveVisible = true,
          drawPilePosition = -1,
        })
      end
      room:moveCards(table.unpack(moves))
    end
  end,
}
local kuiming_delay = fk.CreateTriggerSkill{
  name = "#steam__kuiming_delay",
  anim_type = "negative",
  events = {fk.TurnEnd},
  can_trigger = function (self, event, target, player, data)
    return target == player and player:usedSkillTimes("steam__kuiming", Player.HistoryTurn) > 0 and not player.dead
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if #room:askForDiscard(player, 1, 1, false, "steam__kuiming", true, "jink", "#steam__kuiming-discard") == 0 then
      room:loseHp(player, 1, "steam__kuiming")
    end
  end,
}
kuiming:addRelatedSkill(kuiming_delay)
zhangyu:addSkill(chentu)
zhangyu:addSkill(kuiming)
Fk:loadTranslationTable{
  ["steam__zhangyu"] = "张裕",
  ["#steam__zhangyu"] = "玄目通天",
  ["illustrator:steam__zhangyu"] = "",
  ["designer:steam__zhangyu"] = "左小白",

  ["steam__chentu"] = "谶图",
  [":steam__chentu"] = "出牌阶段或结束阶段开始时，你可以指定一名角色，其可以弃置任意张牌并展示牌堆顶两倍数量的牌，然后你可以交换其中两张牌的顺序"..
  "且其可以获得任意张相邻且颜色相同的牌。",
  ["steam__kuiming"] = "窥命",
  [":steam__kuiming"] = "判定阶段，你可以改为依次进行判定直到结果为♠，然后你将判定牌以任意顺序置于牌堆顶或牌堆底；本回合结束时，"..
  "你需弃置一张【闪】或失去1点体力。",
  ["#steam__chentu-choose"] = "谶图：你可以令一名角色弃置任意张牌，展示牌堆顶两倍的牌，其可能获得其中一些牌",
  ["#steam__chentu-discard"] = "谶图：弃置任意张牌，展示牌堆顶两倍的牌，你可能获得其中一些牌",
  ["#steam__chentu-swap"] = "谶图：你可以交换其中两张牌的位置",
  ["#steam__chentu"] = "谶图：你可以获得其中任意张相邻且颜色相同的牌",
  ["#steam__kuiming_delay"] = "窥命",
  ["#steam__kuiming-discard"] = "窥命：请弃置一张【闪】，否则失去1点体力",
}

local lvbu = General(extension, "steam__lvbu", "qun", 5)
local yizhi = fk.CreateTriggerSkill{
  name = "steam__yizhi",
  anim_type = "drawcard",
  frequency = Skill.Compulsory,
  events = {fk.Damage},
  can_trigger = function (self, event, target, player, data)
    return target == player and player:hasSkill(self) and not player:isAllNude()
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local card1 = room:askForCard(player, 1, 1, true, self.name, false, nil, "#steam__yizhi-recast", player:getCardIds("j"))
    local card2 = room:recastCard(card1, player, self.name)
    if #card2 > 0 and Fk:getCardById(card1[1]):compareColorWith(Fk:getCardById(card2[1]), true) and not player.dead then
      player:drawCards(1, self.name)
    end
  end,
}
local qingzhen = fk.CreateActiveSkill{
  name = "steam__qingzhen",
  anim_type = "offensive",
  card_num = 0,
  min_target_num = 1,
  max_target_num = 3,
  prompt = "#steam__qingzhen",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected)
    return #selected < 3 and to_select ~= Self.id and not Fk:currentRoom():getPlayerById(to_select):isNude()
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    table.insert(effect.tos, player.id)
    room:sortPlayersByAction(effect.tos)
    local targets = table.map(effect.tos, Util.Id2PlayerMapper)
    local tos = {}
    for _, p in ipairs(targets) do
      if not p.dead then
        if p:isNude() then
          table.insert(tos, p.id)
        else
          local card = room:askForDiscard(p, 1, 1, true, self.name, false, nil, "#steam__qingzhen-discard")
          if #card == 0 or Fk:getCardById(card[1]).trueName ~= "slash" then
            table.insert(tos, p.id)
          end
        end
      end
    end
    if #tos == 0 then
      player:setSkillUseHistory(self.name, 0, Player.HistoryPhase)
      return
    end
    room:sortPlayersByAction(tos)
    for _, id in ipairs(tos) do
      local p = room:getPlayerById(id)
      if not p.dead then
        room:damage{
          from = player,
          to = p,
          damage = 1,
          skillName = self.name,
        }
      end
    end
  end,
}
lvbu:addSkill(yizhi)
lvbu:addSkill(qingzhen)
Fk:loadTranslationTable{
  ["steam__lvbu"] = "吕布",
  ["#steam__lvbu"] = "虎视中原",
  ["illustrator:steam__lvbu"] = "",
  ["designer:steam__lvbu"] = "o.O",

  ["steam__yizhi"] = "易帜",
  [":steam__yizhi"] = "锁定技，当你造成伤害后，你重铸区域里的一张牌，若失去牌与获得牌颜色不同，你摸一张牌。",
  ["steam__qingzhen"] = "倾阵",
  [":steam__qingzhen"] = "出牌阶段限一次，你可以令至多三名有牌的其他角色与你依次弃置一张牌，若被弃置的牌均为【杀】，你重置“倾阵”；"..
  "否则你对其中未弃置【杀】的角色各造成1点伤害。",
  ["#steam__yizhi-recast"] = "易帜：请重铸区域里的一张牌",
  ["#steam__qingzhen"] = "倾阵：与至多三名角色各弃置一张牌，若均为【杀】则重置此技能，否则你对未弃置【杀】的角色造成伤害",
  ["#steam__qingzhen-discard"] = "倾阵：请弃置一张牌，若不为【杀】则受到伤害！",
}


local bailingyun = General(extension, "steam__bailingyun", "wei", 3, 3, General.Female)

Fk:loadTranslationTable{
  ["steam__bailingyun"] = "柏灵筠",--MP001
  ["#steam__bailingyun"] = "花玉两似",
  ["illustrator:steam__bailingyun"] = "",
  ["designer:steam__bailingyun"] = "左小白",
  ["~steam__bailingyun"] = "",
}

local steam__qieji = fk.CreateTriggerSkill{
  name = "steam__qieji",
  events = {fk.EventPhaseStart},
  anim_type = "control",
  can_trigger = function(self, event, target, player, data)
    return target == player and player:hasSkill(self) and player.phase == Player.Finish
    and table.find(player.room.alive_players, function(p)
      return p:inMyAttackRange(player) and not p:isKongcheng()
    end) ~= nil
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local targets = table.filter(room.alive_players, function (p) return p:inMyAttackRange(player) and not p:isKongcheng() end)
    if #targets == 0 then return false end
    local tos = player.room:askForChoosePlayers(player, table.map(targets, Util.IdMapper), 1, 999,
    "#steam__qieji-choose", self.name, true)
    if #tos > 0 then
      room:sortPlayersByAction(tos)
      self.cost_data = {tos = tos}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cards = {}
    local tos = table.simpleClone(self.cost_data.tos)
    local targets = table.map(tos, Util.Id2PlayerMapper)
    for _, to in ipairs(targets) do
      local cid = room:askForCardChosen(player, to, "h", self.name)
      table.insert(cards, cid)
    end
    if #cards == 0 then return end
    room:obtainCard(player, cards, true, fk.ReasonPrey, player.id, self.name)
    if player.dead then return end
    if not player:isKongcheng() then
      local n = #cards
      local move = room:askForYiji(player, player:getCardIds("h"), room.alive_players, self.name,
      0, n, "#steam__qieji-yiji:::"..n)
      for pid, cids in pairs(move) do
        if #cids > 0 then
          table.removeOne(tos, pid)
        end
      end
    end
    room:setPlayerMark(player, "@steam__qieji", tostring(#tos))
  end,
}

local steam__qieji_delay = fk.CreateTriggerSkill{
  name = "#steam__qieji_delay",
  events = {fk.DamageInflicted},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    return target == player and player:getMark("@steam__qieji") ~= 0 and data.card and data.card.type == Card.TypeTrick
    and data.damage ~= tonumber(player:getMark("@steam__qieji"))
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local mark = tonumber(player:getMark("@steam__qieji"))
    player:broadcastSkillInvoke("steam__qieji")
    room:notifySkillInvoked(player, "steam__qieji", mark > data.damage and "negative" or "defensive")
    data.damage = mark
  end,

  refresh_events = {fk.TurnStart},
  can_refresh = function(self, event, target, player, data)
    return target == player and player:getMark("@steam__qieji") ~= 0
  end,
  on_refresh = function(self, event, target, player, data)
    player.room:setPlayerMark(player, "@steam__qieji", 0)
  end,
}
steam__qieji:addRelatedSkill(steam__qieji_delay)

bailingyun:addSkill(steam__qieji)

Fk:loadTranslationTable{
  ["steam__qieji"] = "窃机",
  [":steam__qieji"] = "结束阶段，你可以获得攻击范围内含有你的任意名角色的各一张手牌并分配你等量张手牌，然后你于你的下个回合开始前受到的锦囊牌伤害基数改为X（X为这些角色中未获得牌的角色数量）。",
  ["#steam__qieji_delay"] = "窃机",
  ["steam__qieji_active"] = "窃机",
  ["#steam__qieji-choose"] = "窃机：获得攻击范围内含有你的任意名角色的各一张手牌，再分配等量张手牌",
  ["#steam__qieji-yiji"] = "窃机：请分配 %arg 张手牌（点取消自己保留）",
  ["@steam__qieji"] = "窃机",
}

---@param room Room
---@param to ServerPlayer
---@return integer[]
local doHuishi = function (room, to)
  local skillName = "steam__huishi"
  if to.dead then return {} end
  local cards = {}
  local maxNum = 0
  for _, p in ipairs(room.alive_players) do
    maxNum = math.max(maxNum, p:getHandcardNum())
  end
  local toNum = to:getHandcardNum()
  if toNum < maxNum then
    -- 若不为最大，摸1+与手牌最大差值张牌
    cards = to:drawCards(maxNum - toNum + 1, skillName)
  else
    local maxPlayers = table.filter(room.alive_players, function (p)
      return p:getHandcardNum() == maxNum
    end)
    -- 若不为唯一最大，摸1张
    if #maxPlayers > 1 then
      cards = to:drawCards(1, skillName)
    else
      -- 若为唯一最大，弃置(1+与第二大之差)张
      local secondMaxNum = 0
      for _, p in ipairs(room.alive_players) do
        if p:getHandcardNum() < maxNum then
          secondMaxNum = math.max(secondMaxNum, p:getHandcardNum())
        end
      end
      local num = maxNum - secondMaxNum + 1
      cards = room:askForDiscard(to, num, num, false, skillName, false)
    end
  end
  return cards
end

local steam__huishi = fk.CreateActiveSkill{
  name = "steam__huishi",
  anim_type = "control",
  card_num = 0,
  target_num = 1,
  card_filter = Util.FalseFunc,
  prompt = "#steam__huishi",
  target_tip = function (self, to_select, selected, selected_cards, card, selectable, extra_data)
    local maxNum = 0
    for _, p in ipairs(Fk:currentRoom().alive_players) do
      maxNum = math.max(maxNum, p:getHandcardNum())
    end
    local maxPlayers = table.filter(Fk:currentRoom().alive_players, function (p)
      return p:getHandcardNum() == maxNum
    end)
    if #maxPlayers == 1 and maxPlayers[1].id == to_select then
      return "@@steam__huishi_max"
    end
  end,
  target_filter = function(self, to_select, selected)
    return #selected == 0
  end,
  can_use = function(self, player)
    return player:getMark("steam__huishi-phase") == 0 and table.contains(player:getTableMark("@steam__huishi_record"), "steam__huishi_play")
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local to = room:getPlayerById(effect.tos[1])
    room:setPlayerMark(player, "steam__huishi-phase", 1)
    local cards = doHuishi(room, to)
    if not player.dead and #cards > 2 then
      room:removeTableMark(player, "@steam__huishi_record", "steam__huishi_play")
    end
  end,

  on_acquire = function (self, player)
    player.room:setPlayerMark(player, "@steam__huishi_record", {"steam__huishi_play", "steam__huishi_damage", "steam__huishi_death"})
  end,
  on_lose = function (self, player, is_death)
    if is_death then return end
    player.room:setPlayerMark(player, "@steam__huishi_record", 0)
  end,
}

local steam__huishi_trigger = fk.CreateTriggerSkill{
  name = "#steam__huishi_trigger",
  events = {fk.Damaged, fk.Death},
  mute = true,
  can_trigger = function(self, event, target, player, data)
    if target == player then
      if event == fk.Damaged then
        return player:hasSkill(self) and table.contains(player:getTableMark("@steam__huishi_record"), "steam__huishi_damage")
      else
        return player:hasSkill(self, false, true) and table.contains(player:getTableMark("@steam__huishi_record"), "steam__huishi_death")
      end
    end
  end,
  on_trigger = function(self, event, target, player, data)
    self.cancel_cost = false
    local n = 1
    if event == fk.Damaged then n = data.damage end
    for i = 1, n do
      if self.cancel_cost or not self:triggerable(event, target, player, data) then break end
      self:doCost(event, target, player, data)
    end
  end,
  on_cost = function(self, event, target, player, data)
    local room = player.room
    local success, dat = room:askForUseActiveSkill(player, "steam__huishi", "#steam__huishi", true, {skipUse = true})
    if success and dat then
      self.cost_data = {tos = dat.targets}
      return true
    end
    self.cancel_cost = true
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    player:broadcastSkillInvoke("steam__huishi")
    room:notifySkillInvoked(player, "steam__huishi","control")
    local cards = doHuishi(room, to)
    if not player.dead and #cards > 2 then
      room:removeTableMark(player, "@steam__huishi_record", event == fk.Damaged and "steam__huishi_damage" or "steam__huishi_death")
    end
  end,
}
steam__huishi:addRelatedSkill(steam__huishi_trigger)
bailingyun:addSkill(steam__huishi)

Fk:loadTranslationTable{
  ["steam__huishi"] = "洄势",
  [":steam__huishi"] = "出牌阶段限一次，或当你受到1点伤害后，或死亡时，你可以令一名手牌数为/不为唯一最大的角色将手牌调整至不为/为唯一最大，若因此调整的牌数大于2，你需失去一个发动时机。",
  ["#steam__huishi"] = "洄势:令手牌数为/不为唯一最大的角色将手牌调整至不为/为唯一最大",
  ["#steam__huishi_trigger"] = "洄势",
  ["@@steam__huishi_max"] = "唯一最大",
  ["@steam__huishi_record"] = "洄势",
  ["steam__huishi_play"] = "出",
  ["steam__huishi_damage"] = "伤",
  ["steam__huishi_death"] = "死",

  ["$steam__huishi1"] = "",
  ["$steam__huishi2"] = "",
}


local subaru = General(extension, "steam__natsuki_subaru", "shu", 3)  --我也不知道为啥是蜀
local suhui = fk.CreateTriggerSkill{
  name = "steam__suhui",
  anim_type = "control",
  events = {fk.EventPhaseEnd},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target.phase == Player.Finish and not target.dead and
      player:usedSkillTimes(self.name, Player.HistoryRound) == 0
  end,
  on_cost = function (self, event, target, player, data)
    if player.room:askForSkillInvoke(player, self.name, nil, "#steam__suhui-invoke::"..target.id) then
      self.cost_data = {tos = {target.id}}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local hp_record = target:getMark("steam__suhui_record-turn")
    if hp_record == 0 then return end
    for _, p in ipairs(room:getAlivePlayers()) do
      local p_record = table.find(hp_record, function (sub_record)
        return #sub_record == 2 and sub_record[1] == p.id
      end)
      if p_record then
        p.hp = math.min(p.maxHp, p_record[2])
        room:broadcastProperty(p, "hp")
      end
    end
    if not target.dead then
      target:gainAnExtraPhase(Player.Play)
    end
  end,

  refresh_events = {fk.TurnStart},
  can_refresh = function(self, event, target, player, data)
    return target == player
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    local hp_record = {}
    for _, p in ipairs(room.alive_players) do
      table.insert(hp_record, {p.id, p.hp})
    end
    room:setPlayerMark(player, "steam__suhui_record-turn", hp_record)
  end,
}
local xiongxin = fk.CreateActiveSkill{
  name = "steam__xiongxin",
  anim_type = "control",
  card_num = 0,
  target_num = 1,
  prompt = "#steam__xiongxin",
  interaction = function (self)
    return U.CardNameBox { choices = Self:getMark(self.name), }
  end,
  can_use = Util.TrueFunc,
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected, selected_cards)
    return #selected == 0 and to_select ~= Self.id and not table.contains(Self:getTableMark("steam__xiongxin-phase"), to_select) and
      not Fk:currentRoom():getPlayerById(to_select):isKongcheng()
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local target = room:getPlayerById(effect.tos[1])
    room:addTableMark(player, "steam__xiongxin-phase", target.id)
    local cards = table.filter(target:getCardIds("h"), function (id)
      return Fk:getCardById(id).trueName == self.interaction.data
    end)
    U.askForUseRealCard(room, player, cards, nil, self.name,
      "#steam__xiongxin-use::"..target.id..":"..self.interaction.data, {
        bypass_times = true,
        extraUse = true,
        expand_pile = target:getCardIds("h"),
      }, false, true)
    if #cards == 0 then
      room:loseHp(player, 1, self.name)
    end
  end,

  on_acquire = function (self, player, is_start)
    local all_names = {}
    for _, card in ipairs(Fk.cards) do
      if not table.contains(Fk:currentRoom().disabled_packs, card.package.name) and not card.is_derived then
        table.insertIfNeed(all_names, card.trueName)
      end
    end
    player.room:setPlayerMark(player, self.name, all_names)
  end,
}
subaru:addSkill(suhui)
subaru:addSkill(xiongxin)
Fk:loadTranslationTable{
  ["steam__natsuki_subaru"] = "菜月昴",
  ["#steam__natsuki_subaru"] = "异界旅者",
  ["illustrator:steam__natsuki_subaru"] = "",
  ["designer:steam__natsuki_subaru"] = "",

  ["steam__suhui"] = "溯回",
  [":steam__suhui"] = "每轮限一次，一名角色回合结束时，你可以令所有角色将体力值调整为本回合开始时的数值，然后令其执行一个额外的出牌阶段。",
  ["steam__xiongxin"] = "雄心",
  [":steam__xiongxin"] = "出牌阶段每名角色限一次，你可以声明一个牌名并观看一名其他角色的手牌，若其有此牌，你可以使用之，否则你失去1点体力。",

  ["#steam__suhui-invoke"] = "溯回：是否令所有角色将体力值调整为本回合开始时，%dest 获得一个额外出牌阶段？",
  ["#steam__xiongxin"] = "雄心：声明牌名并观看一名角色手牌，若其有此牌可以使用之，否则失去1点体力",
  ["#steam__xiongxin-use"] = "雄心：你可以使用 %dest 手牌中一张【%arg】",
}

local guosi = General(extension, "steam__guosi", "han", 4)
Fk:loadTranslationTable{
  ["steam__guosi"] = "郭汜",
  ["#steam__guosi"] = "鸷狠诡戾",
  ["designer:steam__guosi"] = "老猫",
  ["illustrator:steam__guosi"] = "秋呆呆",
  ["~steam__guosi"] = "",
}

local steam__tansi = fk.CreateViewAsSkill{
  name = "steam__tansi",
  anim_type = "offensive",
  pattern = "slash,snatch",
  prompt = "#steam__tansi",
  interaction = function(self)
    local all_choices = self.pattern:split(",")
    local choices = U.getViewAsCardNames(Self, self.name, all_choices)
    if #choices > 0 then
      return U.CardNameBox { choices = choices, all_choices = all_choices }
    end
  end,
  card_filter = function(self, to_select, selected)
    local name = self.interaction.data
    if #selected == 0 and name then
      if name == "slash" then
        return Fk:getCardById(to_select):getMark("@@steam__tansi-inhand-turn") ~= 0
      else
        return Fk:getCardById(to_select).trueName == "slash"
      end
    end
  end,
  view_as = function(self, cards)
    local name = self.interaction.data
    if not name or #cards ~= 1 then return nil end
    local c = Fk:cloneCard(name)
    c.skillName = self.name
    c:addSubcard(cards[1])
    return c
  end,
  before_use = function(self, player, use)
    local room = player.room
    if not use.extraUse and use.card.trueName == "snatch" then
      player:addCardUseHistory("slash")
    end
    if use.card.trueName == "slash" then
      use.extraUse = true
    end
    local cid = use.card.subcards[1]
    if cid and Fk:getCardById(cid).trueName == "slash" and Fk:getCardById(cid):getMark("@@steam__tansi-inhand-turn") ~= 0 then
      use.extra_data = use.extra_data or {}
      use.extra_data.steam__tansi_both = true
    end
  end,
  enabled_at_play = function(self, player)
    return not player:isKongcheng()
  end,
  enabled_at_response = function (self, player, response)
    return not response
  end,

  on_acquire = function (self, player, is_start)
    local hand = player:getCardIds("h")
    if #hand == 0 then return end
    local room = player.room
    local get = {}
    room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function(e)
      for _, move in ipairs(e.data) do
        if move.to == player.id and move.toArea == Player.Hand then
          for _, info in ipairs(move.moveInfo) do
            table.insert(get, info.cardId)
          end
        end
      end
      return false
    end, Player.HistoryTurn)
    for _, id in ipairs(hand) do
      if table.contains(get, id) then
        room:setCardMark(Fk:getCardById(id), "@@steam__tansi-inhand-turn", 1)
      end
    end
  end,
  on_lose = function (self, player, is_death)
    local room = player.room
    for _, id in ipairs(player:getCardIds("h")) do
      room:setCardMark(Fk:getCardById(id), "@@steam__tansi-inhand-turn", 0)
    end
  end,
}

local steam__tansi_targetmod = fk.CreateTargetModSkill{
  name = "#steam__tansi_targetmod",
  bypass_times = function(self, player, skill, scope, card, to)
    return card and card.trueName == "slash" and table.contains(card.skillNames, steam__tansi.name)
  end,
  bypass_distances = function(self, player, skill, card, to)
    if card and table.contains(card.skillNames, steam__tansi.name) then
      local cid = card.subcards[1]
      return cid and Fk:getCardById(cid).trueName == "slash" and Fk:getCardById(cid):getMark("@@steam__tansi-inhand-turn") ~= 0
    end
  end,
}
steam__tansi:addRelatedSkill(steam__tansi_targetmod)

-- 为顺手牵羊加上杀的次数检测
local steam__tansi_prohibit = fk.CreateProhibitSkill{
  name = "#steam__tansi_prohibit",
  is_prohibited = function(self, from, to, card)
    if from and to and card and card.name == "snatch" and table.contains(card.skillNames, steam__tansi.name) then
      local cid = card.subcards[1]
      if not cid then return true end
      local slash = Fk:getCardById(cid)
      return not slash.skill:withinTimesLimit(from, Player.HistoryPhase, slash, "slash", to)
    end
  end,
}
steam__tansi:addRelatedSkill(steam__tansi_prohibit)

local steam__tansi_trigger = fk.CreateTriggerSkill{
  name = "#steam__tansi_trigger",
  mute = true,
  events = {fk.CardUsing},
  can_trigger = function(self, event, target, player, data)
    return target == player and data.extra_data and data.extra_data.steam__tansi_both
  end,
  on_trigger = function (self, event, target, player, data)
    data.disresponsiveList = table.map(player.room.alive_players, Util.IdMapper)
  end,

  refresh_events = {fk.AfterCardsMove},
  can_refresh = function(self, event, target, player, data)
    return player:hasSkill(steam__tansi, true)
  end,
  on_refresh = function(self, event, target, player, data)
    local room = player.room
    for _, move in ipairs(data) do
      if move.to == player.id and move.toArea == Player.Hand then
        for _, info in ipairs(move.moveInfo) do
          local id = info.cardId
          if table.contains(player.player_cards[Player.Hand], info.cardId) then
            room:setCardMark(Fk:getCardById(id), "@@steam__tansi-inhand-turn", 1)
          end
        end
      end
    end
  end,
}
steam__tansi:addRelatedSkill(steam__tansi_trigger)

guosi:addSkill(steam__tansi)

Fk:loadTranslationTable{
  ["steam__tansi"] = "贪饲",
  [":steam__tansi"] = "你可以将【杀】当作【顺手牵羊】使用，或将本回合内获得的牌当作【杀】使用，因前者/后者使用的【杀】计入/不计入额定使用【杀】次数，若均满足，此牌无距离限制且不能被响应。",
  -- 均满足：指此牌为本回合获得的【杀】；计入【杀】次数=受【杀】次数限制；不计入【杀】=不受次数限制
  ["@@steam__tansi-inhand-turn"] = "贪饲",
  ["#steam__tansi"] = "贪饲：将【杀】当作【顺手牵羊】使用(计入杀次数)、本回合内获得的牌当作无次数限制【杀】使用",
  
  ["$steam__tansi1"] = "此机，我怎么会错失。",
  ["$steam__tansi2"] = "你的东西，现在是我的了！",
  ["$steam__tansi3"] = "连发伺动，顺手可得。",
}

local putin = General(extension, "steam__putin", "west", 4)
Fk:loadTranslationTable{
  ["steam__putin"] = "普京",
  ["#steam__putin"] = "冬临大帝",
  ["illustrator:steam__putin"] = "AI",
  ["designer:steam__putin"] = "杨林",
  ["~steam__putin"] = "",
}

local steam__bairen = fk.CreateTriggerSkill{
  name = "steam__bairen",
  frequency = Skill.Compulsory,
  events = {fk.DamageInflicted},
  anim_type = "defensive",
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target == player and player.phase == Player.NotActive and data.from
    and data.from == player.room.current
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if player:getMark("@steam__bairen-turn") == "0" then return true end
    local mark = player:getMark("@steam__bairen-turn")
    if mark > data.damage then
      room:removePlayerMark(player, "@steam__bairen-turn", data.damage)
    else
      room:setPlayerMark(player, "@steam__bairen-turn", "0")
      data.damage = mark
    end
  end,

  refresh_events = {fk.TurnStart},
  can_refresh = function (self, event, target, player, data)
    return player:hasSkill(self, true) and player.phase == Player.NotActive
  end,
  on_refresh = function (self, event, target, player, data)
    player.room:setPlayerMark(player, "@steam__bairen-turn", player.room:getBanner("RoundCount") or 1)
  end,

  on_lose = function (self, player, is_death)
    player.room:setPlayerMark(player, "@steam__bairen-turn", 0)
  end,
}
putin:addSkill(steam__bairen)

Fk:loadTranslationTable{
  ["steam__bairen"] = "百韧",
  [":steam__bairen"] = "锁定技，你的回合外，当前回合角色至多对你造成X点伤害（X为当前轮次数）。",
  ["@steam__bairen-turn"] = "百韧",

  ["$steam__bairen1"] = "",
  ["$steam__bairen2"] = "",
}

local wansheng = fk.CreateViewAsSkill{
  name = "steam__wansheng",
  pattern = ".",
  prompt = function (self)
    local to = Self:getMark("steam__wansheng_tar-turn")
    if to ~= 0 then
      return "#steam__wansheng:"..to
    end
    return " "
  end,
  expand_pile = function()
    local to = Fk:currentRoom():getPlayerById(Self:getMark("steam__wansheng_tar-turn"))
    if to then
      return to:getCardIds("h")
    end
    return {}
  end,
  card_filter = function(self, to_select, selected)
    local to = Fk:currentRoom():getPlayerById(Self:getMark("steam__wansheng_tar-turn"))
    if to and table.contains(to:getCardIds("h"), to_select) then
      -- 令客户端强制同步锁视
      Fk:filterCard(to_select, to)
      local card = Fk:getCardById(to_select)
      if #selected == 0 and not table.contains(Self:getTableMark("@steam__wansheng_suit-turn"), card:getSuitString(true)) then
        if Fk.currentResponsePattern == nil then
          return Self:canUse(card) and not Self:prohibitUse(card)
        else
          return Exppattern:Parse(Fk.currentResponsePattern):match(card)
        end
      end
    end
  end,
  view_as = function(self, cards)
    if #cards ~= 1 then return end
    return Fk:getCardById(cards[1])
  end,
  before_use = function (self, player, use)
    player.room:addTableMark(player, "@steam__wansheng_suit-turn", use.card:getSuitString(true))
  end,
  enabled_at_play = function(self, player)
    return player:getMark("steam__wansheng_tar-turn") ~= 0
  end,
  enabled_at_response = function(self, player, response)
    if not response and Fk.currentResponsePattern then
      local to = Fk:currentRoom():getPlayerById(player:getMark("steam__wansheng_tar-turn"))
      return to and table.find(to:getCardIds("h"), function (id)
        return Exppattern:Parse(Fk.currentResponsePattern):match(Fk:getCardById(id))
      end)
    end
  end,
}
local steam__wansheng_trigger = fk.CreateTriggerSkill{
  name = "#steam__wansheng_trigger",
  anim_type = "control",
  events = {fk.EventPhaseStart},
  can_trigger = function(self, event, target, player, data)
    if target.phase ~= Player.Start or not player:hasSkill(wansheng) then return false end
    return player:usedSkillTimes(self.name, Player.HistoryRound) == 0 -- 取巧
  end,
  on_cost = function (self, event, target, player, data)
    local targets = table.map(player.room:getOtherPlayers(player, false), Util.IdMapper)
    local tos = player.room:askForChoosePlayers(player, targets, 1, 1, "#steam__wansheng-choose", self.name, true)
    if #tos > 0 then
      self.cost_data = {tos = tos}
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    player:broadcastSkillInvoke(wansheng.name)
    local to = room:getPlayerById(self.cost_data.tos[1])
    to:filterHandcards()
    room:setPlayerMark(player, "steam__wansheng_tar-turn", to.id)
    room:setPlayerMark(player, "@steam__wansheng-turn", to.general)
  end,

  refresh_events = {fk.TurnEnd},
  can_refresh = function (self, event, target, player, data)
    return player:getMark("steam__wansheng_tar-turn") ~= 0
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    local toId = player:getMark("steam__wansheng_tar-turn")
    local toNum, myNum = 0, 0
    room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function(e)
      for _, move in ipairs(e.data) do
        local loseNum = #table.filter(move.moveInfo, function (info)
          return info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip
        end)
        if move.from == player.id then
          myNum = myNum + loseNum
        elseif move.from == toId then
          toNum = toNum + loseNum
        end
      end
      return false
    end, Player.HistoryTurn)
    if toNum <= myNum then
      RUtil.resetSkill(player, self.name)
    end
  end,
}
wansheng:addRelatedSkill(steam__wansheng_trigger)

local steam__wansheng_visibility = fk.CreateVisibilitySkill{
  name = "#steam__wansheng_visibility",
  card_visible = function(self, player, card)
    local to = Fk:currentRoom():getPlayerById(player:getMark("steam__wansheng_tar-turn"))
    if to and table.contains(to:getCardIds("h"), card.id) then
      return true
    end
  end
}
wansheng:addRelatedSkill(steam__wansheng_visibility)

putin:addSkill(wansheng)

Fk:loadTranslationTable{
  ["steam__wansheng"] = "万乘",
  [":steam__wansheng"] = "轮次技，任意角色的准备阶段，你可指定一名其他角色，然后当前回合内：指定角色的手牌对你可见，且你可将其手牌当你的手牌使用（每回合每种花色各限一次）；当前回合结束时，若指定角色失去的牌数不多于你，重置此技能的次数。",
  ["#steam__wansheng_trigger"] = "万乘",
  ["#steam__wansheng"] = "万乘：你可以使用 %src 的手牌(每牌名限一次)",
  ["#steam__wansheng-choose"] = "万乘：指定一名其他角色，本回合其手牌对你可见且你可使用之",
  ["@steam__wansheng-turn"] = "万乘目标",
  ["@steam__wansheng_suit-turn"] = "万乘",

  ["$steam__wansheng1"] = "",
  ["$steam__wansheng2"] = "",
}


local mengda = General(extension, "steam__mengda", "han", 4)
mengda.subkingdom = "wei"
Fk:loadTranslationTable{
  ["steam__mengda"] = "孟达",
  ["#steam__mengda"] = "反复苟得",
  ["designer:steam__mengda"] = "emo公主",
  ["illustrator:steam__mengda"] = "错落宇宙",
}

local daigu = fk.CreateTriggerSkill{
  name = "steam__daigu",
  frequency = Skill.Compulsory,
  events = {fk.CardUseFinished},
  anim_type = "drawcard",
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self) and target.kingdom ~= player.kingdom and target.phase == Player.Play and
    not table.contains(player:getTableMark("@steam__daigu"), target.kingdom)
    and table.every(player.room.alive_players, function (p) return not p.dying end)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local cardType, kingdom = data.card:getTypeString(), target.kingdom
    local use = U.askForUseRealCard(room, player, nil, ".|.|.|.|.|"..cardType, self.name, "#steam__daigu-use:::"..cardType..":"..kingdom)
    if not use then
      player:drawCards(2, self.name)
      if player.dead then return end
      room:addTableMark(player, "@steam__daigu", kingdom)
      if table.every(room.alive_players, function (p)
        return p.kingdom == player.kingdom or table.contains(player:getTableMark("@steam__daigu"), p.kingdom)
      end) then
        local skillToGet = "goude"
        local kingdoms = {}
        for _, p in ipairs(room.alive_players) do
          if p.kingdom ~= player.kingdom then
            table.insertIfNeed(kingdoms, p.kingdom)
          end
        end
        if #kingdoms > 0 then
          local choice = room:askForChoice(player, kingdoms, self.name, "#steam__daigu-change")
          room:changeKingdom(player, choice, true)
          if player.dead then return end
          local skills = {}
          local ignoreBlacklist = false -- 是否无视禁表
          local isLord = (player.role == "lord" and player.role_shown)
          for _, g in pairs(Fk.generals) do
            if not g.hidden and not g.total_hidden then
              if ignoreBlacklist or Fk:canUseGeneral(g.name) then
                for _, skill in ipairs(g.skills) do
                  if table.contains(skill.attachedKingdom or {}, player.kingdom) and not (skill.lordSkill and not isLord) then
                    table.insertIfNeed(skills, skill.name)
                  end
                end
              end
            end
          end
          if #skills > 0 then
            skillToGet = table.random(skills)
          end
        end
        room:handleAddLoseSkills(player, "-"..self.name.."|"..skillToGet)
        if not player.dead then
          U.askForUseVirtualCard(room, player, "slash", nil, self.name, nil, false, true, true, true)
        end
      end
    end
  end,

  on_lose = function (self, player)
    player.room:setPlayerMark(player, "@steam__daigu", 0)
  end,
}
mengda:addSkill(daigu)
mengda:addRelatedSkill("goude")
Fk:loadTranslationTable{
  ["steam__daigu"] = "待沽",
  [":steam__daigu"] = "锁定技，与你势力不同的角色于出牌阶段使用牌后，若无濒死角色，你需使用一张同类型牌，否则你摸两张牌且对此势力不再询问，若无可发动势力，你变更为场上其他势力，将本技能替换为当前势力的势力技（若无改为【苟得】），然后视为使用一张【杀】。",
  ["@steam__daigu"] = "待沽",
  ["#steam__daigu-use"] = "待沽：你需使用一张%arg，否则摸2张牌，且不再对【%arg2】势力询问【待沽】",
  ["#steam__daigu-change"] = "待沽：请变为一个场上势力！",

  ["$steam__daigu1"] = "我有武力傍身，必可待价而沽。",
  ["$steam__daigu2"] = "气节？可当粟米果腹乎！",
}

local wenyuan = General(extension, "steam__wenyuan", "shu", 3, 3, General.Female)
Fk:loadTranslationTable{
  ["steam__wenyuan"] = "文鸳",
  ["#steam__wenyuan"] = "揾泪红袖",
  ["designer:steam__wenyuan"] = "从珂",
  ["illustrator:steam__wenyuan"] = "匠人绘",
  ["~steam__wenyuan"] = "伯约，回家了。",
}

local kengqiang = fk.CreateViewAsSkill{
  name = "steam__kengqiang",
  anim_type = "offensive",
  pattern = "duel,fire_attack",
  prompt = "#steam__kengqiang",
  interaction = function(self)
    return U.CardNameBox { choices = {"duel", "fire_attack"} }
  end,
  card_filter = Util.FalseFunc,
  view_as = function(self, cards)
    if not self.interaction.data then return nil end
    local c = Fk:cloneCard(self.interaction.data)
    c.skillName = self.name
    return c
  end,
  enabled_at_play = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) < 2
  end,
  enabled_at_response = Util.FalseFunc,
}
local kengqiang_trigger = fk.CreateTriggerSkill{
  name = "#steam__kengqiang_trigger",
  anim_type = "offensive",
  main_skill = kengqiang, 
  events = {fk.DamageCaused},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(kengqiang) then
      return player:usedSkillTimes(kengqiang.name, Player.HistoryPhase) < 2
    end
  end,
  on_cost = function (self, event, target, player, data)
    if player.room:askForSkillInvoke(player, self.name, nil, "#steam__qingshi-damage:"..data.to.id) then
      self.cost_data = {tos = {data.to.id}}
      return true
    end
  end,
  on_use = function (self, event, target, player, data)
    player:broadcastSkillInvoke(kengqiang.name)
    data.damage = data.damage + 1
  end,
}
kengqiang:addRelatedSkill(kengqiang_trigger)
wenyuan:addSkill(kengqiang)

Fk:loadTranslationTable{
  ["steam__kengqiang"] = "铿锵",
  [":steam__kengqiang"] = "出牌阶段限两次，你可以视为使用一张【火攻】或【决斗】；你造成伤害时，你可以令此伤害+1。",
  ["#steam__kengqiang_trigger"] = "铿锵",
  ["#steam__qingshi-damage"] = "铿锵：你对%src造成伤害，可令伤害值+1",
  ["#steam__kengqiang"] = "铿锵：视为使用一张【火攻】或【决斗】",

  ["$steam__kengqiang1"] = "女子着征袍，战意越关山。",
  ["$steam__kengqiang2"] = "兴武效妇好，挥钺断苍穹！",
}

local shangjue = fk.CreateActiveSkill{
  name = "steam__shangjue",
  frequency = Skill.Limited,
  card_num = 0,
  target_num = 0,
  prompt = "#steam__shangjue",
  card_filter = Util.FalseFunc,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryGame) == 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    if player.dead then return end
    local n = player.hp - 1
    if n > 0 then
      room:loseHp(player, n, self.name)
    elseif n < 0 then
      room:recover { num = -n, skillName = self.name, who = player, recoverBy = player }
    end
    if player.dead then return end
    room:changeMaxHp(player, 1)
    if player.dead then return end
    local ids = room:getBanner("@$CenterArea") or {}
    if #ids > 0 then
      room:obtainCard(player, ids, true, fk.ReasonJustMove, player.id, self.name)
    end
  end,
}
local shangjue_trigger = fk.CreateTriggerSkill{
  name = "#steam__shangjue_trigger",
  anim_type = "offensive",
  main_skill = shangjue,
  events = {fk.EnterDying},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(shangjue) then
      return player:usedSkillTimes(shangjue.name, Player.HistoryGame) == 0
    end
  end,
  on_use = function (self, event, target, player, data)
    player:broadcastSkillInvoke(shangjue.name)
    shangjue:onUse(player.room, { from = player.id, tos = {}, cards = {} })
  end,
}
shangjue:addRelatedSkill(shangjue_trigger)
shangjue.CenterArea = true
wenyuan:addSkill(shangjue)

Fk:loadTranslationTable{
  ["steam__shangjue"] = "殇决",
  [":steam__shangjue"] = "限定技，当你进入濒死时或出牌阶段，你可以将体力调整至1点，加1点体力上限，并获得中央区所有牌。",
  ["#steam__shangjue"] = "殇决：将体力调整至1点，加1点体力上限，并获得中央区所有牌",
  ["#steam__shangjue_trigger"] = "殇决",

  ["$steam__shangjue1"] = "伯约，奈何桥畔，再等我片刻。",
  ["$steam__shangjue2"] = "与君同生共死，岂可空待黄泉！",
}

local wenyuan2 = General(extension, "steam2__wenyuan", "han", 3, 3, General.Female)
Fk:loadTranslationTable{
  ["steam2__wenyuan"] = "文鸳",
  ["#steam2__wenyuan"] = "揾泪红袖",
  ["designer:steam2__wenyuan"] = "从珂",
  ["illustrator:steam2__wenyuan"] = "VE",
  ["~steam2__wenyuan"] = "秋风起，天意凉，独立黄昏愁满肠。",
}

local kunli = fk.CreateTriggerSkill{
  name = "steam__kunli",
  anim_type = "drawcard",
  events = {fk.TurnEnd},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      local drawNum, damageNum = 0, 0
      player.room.logic:getActualDamageEvents(1, function(e)
        local damage = e.data[1]
        if damage.from == player then
          damageNum = damageNum + damage.damage
        end
        return false
      end)
      player.room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function(e)
        for _, move in ipairs(e.data) do
          if move.to == player.id and move.toArea == Card.PlayerHand then
            drawNum = drawNum + #table.filter(move.moveInfo, function (info)
              return info.fromArea == Card.DrawPile
            end)
          end
        end
        return false
      end, Player.HistoryTurn)
      if drawNum > 0 and drawNum <= damageNum then
        self.cost_data = {both = drawNum == damageNum}
        return true
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    player:drawCards(2, self.name)
    if self.cost_data.both then
      room:handleAddLoseSkills(player, "-"..self.name.."|steam__qingbei")
    end
  end,
}
wenyuan2:addSkill(kunli)
wenyuan2:addRelatedSkill("steam__qingbei")

Fk:loadTranslationTable{
  ["steam__kunli"] = "困励",
  [":steam__kunli"] = "每回合结束时，若你本回合摸牌数大于0且不大于造成的伤害数，你摸两张牌，若相等，你失去此技能并获得“倾北”。",
  
  ["$steam__kunli1"] = "回首万重山，难阻轻舟一叶。",
  ["$steam__kunli2"] = "已过山穷水尽，前有柳暗花明。",
}

local kuichi = fk.CreateTriggerSkill{
  name = "steam__kuichi",
  anim_type = "drawcard",
  events = {fk.TurnStart},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) then
      local turnEvent = player.room.logic:getCurrentEvent():findParent(GameEvent.Turn, true)
      if not turnEvent then return false end
      local lastTurn
      local events = player.room.logic.event_recorder[GameEvent.Turn] or Util.DummyTable
      for i = #events, 1, -1 do
        local e = events[i]
        if e.id < turnEvent.id then
          lastTurn = e
          break
        end
      end
      if not lastTurn then return false end
      local drawNum, damageNum = 0, 0
      -- 倒序找
      player.room.logic:getActualDamageEvents(1, function(e)
        if e.id > turnEvent.id then return false end
        local damage = e.data[1]
        if damage.from == player then
          damageNum = damageNum + damage.damage
        end
        return false
      end, nil, lastTurn.id)
      player.room.logic:getEventsByRule(GameEvent.MoveCards, 1, function(e)
        if e.id > turnEvent.id then return false end
        for _, move in ipairs(e.data) do
          if move.to == player.id and move.toArea == Card.PlayerHand then
            drawNum = drawNum + #table.filter(move.moveInfo, function (info)
              return info.fromArea == Card.DrawPile
            end)
          end
        end
        return false
      end, lastTurn.id)
      if damageNum > 0 and damageNum <= drawNum then
        self.cost_data = {both = drawNum == damageNum}
        return true
      end
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local tos = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1, "#steam__kuichi-damage", self.name, false)
    if #tos > 0 then
      room:damage { from = player, to = room:getPlayerById(tos[1]), damage = 1, skillName = self.name }
    end
    if self.cost_data.both then
      room:handleAddLoseSkills(player, "-"..self.name.."|steam__qingbei")
    end
  end,
}
wenyuan2:addSkill(kuichi)
wenyuan2:addRelatedSkill("steam__ranji")

Fk:loadTranslationTable{
  ["steam__kuichi"] = "匮饬",
  [":steam__kuichi"] = "每回合开始时，若你上回合造成的伤害数大于0且不大于摸牌数，你造成1点伤害，若相等，你失去此技能并获得“燃己”。",
  ["#steam__kuichi-damage"] = "匮饬：请对一名角色造成1点伤害",
  
  ["$steam__kuichi1"] = "久战沙场，遗伤无数。",
  ["$steam__kuichi2"] = "人无完人，千虑亦有一失。",
}


local shiji = General(extension, "steam__shiji", "wu", 4)

local subei = fk.CreateActiveSkill{
  name = "steam__subei",
  anim_type = "drawcard",
  target_num = 0,
  prompt = function (self)
    if Self:usedSkillTimes(self.name, Player.HistoryPhase) == 0 then
      return "#steam__subei:::"..Self.maxHp
    else
      return "#steam__subei0"
    end
  end,
  can_use = function (self, player, card, extra_data)
    if player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 then
      return true
    elseif player:getMark("steam__subei_rest-phase") == 0 then
      return #table.filter(player:getCardIds("h"), function (id)
        return Fk:getCardById(id).is_damage_card
      end) == player:getMark("@steam__subei-phase")
    end
  end,
  card_filter = function(self, to_select, selected, player)
    if player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 then
      return #selected < player.maxHp
    end
    return false
  end,
  feasible = function (self, selected, selected_cards, player)
    if player:usedSkillTimes(self.name, Player.HistoryPhase) == 0 then
      return #selected_cards > 0
    else
      return #selected_cards == 0
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    if #effect.cards > 0 then
      room:setPlayerMark(player, "@steam__subei-phase", #effect.cards)
      room:recastCard(effect.cards, player, self.name)
    else
      room:addPlayerMark(player, "steam__subei_rest-phase")
      player:setSkillUseHistory(self.name, 0, Player.HistoryPhase)
      player:showCards(player:getCardIds("h"))
    end
  end,
}
local shichu = fk.CreateTriggerSkill{
  name = "steam__shichu",
  anim_type = "drawcard",
  events = {fk.CardUsing},
  can_trigger = function(self, event, target, player, data)
    if target == player and player:hasSkill(self) and #player:getTableMark("steam__shichu-turn") < 2 then
      local red, black = 0, 0
      player.room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function(e)
        for _, move in ipairs(e.data) do
          if move.toArea == Card.DiscardPile then
            for _, info in ipairs(move.moveInfo) do
              if Fk:getCardById(info.cardId).color == Card.Red then
                red = red + 1
              elseif Fk:getCardById(info.cardId).color == Card.Black then
                black = black + 1
              end
            end
          end
        end
      end, Player.HistoryTurn)
      return red == black
    end
  end,
  on_cost = function (self, event, target, player, data)
    local all_choices = {"draw1", "steam__shichu_damage", "Cancel"}
    local choices = table.filter(all_choices, function (ch) return not table.contains(player:getTableMark("steam__shichu-turn"), ch) end)
    if not data.card.is_damage_card then
      table.removeOne(choices, "steam__shichu_damage")
    end
    if #choices <= 1 then return false end
    local choice = player.room:askForChoice(player, choices, self.name, "", false, all_choices)
    if choice ~= "Cancel" then
      player.room:addTableMark(player, "steam__shichu-turn", choice)
      self.cost_data = {choice = choice}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    if self.cost_data.choice == "draw1" then
      player:drawCards(1, self.name)
    else
      data.additionalDamage = (data.additionalDamage or 0) + 1
    end
  end,
}
shichu.CenterArea = true
shiji:addSkill(subei)
shiji:addSkill(shichu)
Fk:loadTranslationTable{
  ["steam__shiji"] = "施绩",
  ["#steam__shiji"] = "威重柱国",
  ["illustrator:steam__shiji"] = "AI",
  ["designer:steam__shiji"] = "小叶子",

  ["steam__subei"] = "肃备",
  [":steam__subei"] = "出牌阶段限一次，你可以重铸至多你体力上限张牌；出牌阶段，若你以此重铸过牌且手中的伤害牌数为X，你可展示所有手牌并令此技能本阶段改为限两次（X为你上次以此重铸的牌数）。",
  ["#steam__subei"] = "肃备：你可以重铸至多%arg张牌",
  ["#steam__subei0"] = "肃备：你可以展示所有手牌，重置此技能(限一次！)",
  ["@steam__subei-phase"] = "肃备",

  ["steam__shichu"] = "势出",
  [":steam__shichu"] = "每回合各限一次，你使用牌时，若本回合进入弃牌堆的两种颜色牌数量相同，你可以摸一张牌或令此牌伤害+1。",
  ["steam__shichu_damage"] = "此牌伤害+1",
}

local liubei = General(extension, "steam__liubei", "shu", 4)
liubei.hidden = true
liubei.subkingdom = "han"
local yanren = fk.CreateActiveSkill{
  name = "steam__yanren",
  anim_type = "support",
  card_num = 0,
  target_num = 0,
  prompt = "#steam__yanren",
  interaction = function(self)
    local all_choices = {"steam__yanren1", "steam__yanren2"}
    local choices = table.filter(all_choices, function (choice)
      return Self:getMark(choice.."-phase") == 0
    end)
    return UI.ComboBox { choices = choices, all_choices = all_choices }
  end,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) < 2
  end,
  card_filter = Util.FalseFunc,
  feasible = function(self, selected, selected_cards)
    if self.interaction.data == "steam__yanren1" then
      return true
    elseif self.interaction.data == "steam__yanren2" then
      return Self:getHandcardNum() > 1 and #Fk:currentRoom().alive_players > 1
    end
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    room:setPlayerMark(player, self.interaction.data.."-phase", 1)
    if self.interaction.data == "steam__yanren1" then
      player:drawCards(3, self.name)
      if player.dead or player:getHandcardNum() < 2 or #room:getOtherPlayers(player) == 0 then return end
      local n = (player:getHandcardNum() + 1) // 2
      room:askForYiji(player, player:getCardIds("h"), room:getOtherPlayers(player), self.name, n, 999, "#steam__yanren-give:::"..n)
    else
      local n = (player:getHandcardNum() + 1) // 2
      room:askForYiji(player, player:getCardIds("h"), room:getOtherPlayers(player), self.name, n, 999, "#steam__yanren-give:::"..n)
      if player.dead then return end
      player:drawCards(3, self.name)
    end
  end,
}
local renyan = fk.CreateTriggerSkill{
  name = "steam__renyan",
  anim_type = "offensive",
  events = {fk.AfterCardsMove},
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) or player:getHandcardNum() ~= 1 then return end
    for _, move in ipairs(data) do
      if move.to == player.id and move.toArea == Card.PlayerHand then
        return true
      end
      if move.from == player.id then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerHand then
            return true
          end
        end
      end
    end
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local tos = room:askForChoosePlayers(player, table.map(room.alive_players, Util.IdMapper), 1, 1,
      "#steam__renyan-choose", self.name, true)
    if #tos > 0 then
      self.cost_data = {tos = tos}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local to = room:getPlayerById(self.cost_data.tos[1])
    local suit = Fk:getCardById(player:getCardIds("h")[1]).suit
    player:showCards(player:getCardIds("h"))
    if not to.dead then
      room:damage{
        from = player,
        to = to,
        damage = 1,
        damageType = fk.FireDamage,
        skillName = self.name,
      }
    end
    if player.dead then return end
    local mark = player:getTableMark("steam__renyan-turn")
    table.remove(mark, #mark)
    if table.contains(mark, suit) then
      room:invalidateSkill(player, self.name, "-turn")
      if player:getHandcardNum() < player:getMaxCards() then
        player:drawCards(player:getMaxCards() - player:getHandcardNum(), self.name)
      end
    end
  end,

  refresh_events = {fk.CardShown},
  can_refresh = function (self, event, target, player, data)
    return target == player and player:hasSkill(self, true)
  end,
  on_refresh = function (self, event, target, player, data)
    local mark = player:getTableMark("steam__renyan-turn")
    for _, id in ipairs(data.cardIds) do
      table.insert(mark, Fk:getCardById(id).suit)
    end
    player.room:setPlayerMark(player, "steam__renyan-turn", mark)
  end,
}
liubei:addSkill(yanren)
liubei:addSkill(renyan)
Fk:loadTranslationTable{
  ["steam__liubei"] = "刘备",
  ["#steam__liubei"] = "熔裁昭日",
  ["illustrator:steam__liubei"] = "无鳏",
  ["designer:steam__liubei"] = "云雀",

  ["steam__yanren"] = "宴仁",
  [":steam__yanren"] = "出牌阶段各限一次，你可以：1.摸三张牌，然后分配至少半数手牌；2.分配至少半数手牌，然后摸三张牌。",
  ["steam__renyan"] = "纫炎",
  [":steam__renyan"] = "当你的手牌数变化为一后，你可以展示之并对一名角色造成1点火焰伤害，若你因此展示的牌与本回合展示过的牌花色相同，你将"..
  "手牌摸至上限且此技能本回合失效。",
  ["#steam__yanren"] = "宴仁：选择一项",
  ["steam__yanren1"] = "摸三张牌，分配至少半数手牌",
  ["steam__yanren2"] = "分配至少半数手牌，摸三张牌",
  ["#steam__yanren-give"] = "宴仁：将至少%arg张手牌分配给其他角色",
  ["#steam__renyan-choose"] = "纫炎：你可以展示手牌，对一名角色造成1点火焰伤害",

  ["$steam__yanren1"] = "我将丹心酿烈酒，且取一觞慰风尘。",
  ["$steam__yanren2"] = "余酒尽倾江海中，与君共宴天下人。",
  ["$steam__renyan1"] = "卿乃志同之股肱，国贼当前，可欲诛之。",
  ["$steam__renyan2"] = "请君振炎汉之武运，除篡国之逆贼。",
  ["~steam__liubei"] = "醉泣江山君莫笑，似我刘备有几人。",
}

local majun = General(extension, "steam__majun", "wei", 3)

Fk:loadTranslationTable{
  ["steam__majun"] = "马钧",
  ["#steam__majun"] = "大魏发明家",
  ["cv:steam__majun"] = "",
  ["designer:steam__majun"] = "emo公主",
  ["illustrator:steam__majun"] = "第七个橘子",
}

local qiaosi_card_record = {}

local qiaosi = fk.CreateTriggerSkill{
  name = "steam__qiaosi",
  frequency = Skill.Compulsory,
  anim_type = "drawcard",
  events = {fk.GameStart},
  can_trigger = function(self, event, target, player, data)
    return player:hasSkill(self)
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    local pname = player._splayer:getScreenName()
    if pname and pname ~= "" then
      local cards = qiaosi_card_record[pname]
      if cards and #cards > 0 then
        local get = {}
        for _, info in ipairs(cards) do
          local cardname = info[1]
          local fakecard = Fk:cloneCard(cardname)
          if cardname == "xbow" or -- 特判一下连弩
           (not fakecard.is_derived and fakecard.package and not table.contains(room.disabled_packs, fakecard.package.name)) then
            table.insert(get, room:printCard(info[1], info[2], info[3]).id)
          end
        end
        if #get == 0 then return end
        room:obtainCard(player, get, false, fk.ReasonJustMove, player.id, self.name)
      end
    end
  end,
}
majun:addSkill(qiaosi)

-- 注意：由于退出房间导致checkNoHuman导致的结束游戏，不会记录
local qiaosi_record = fk.CreateTriggerSkill{
  name = "steam__qiaosi_record",
  global = true,

  refresh_events = {fk.GameFinished, fk.Death},
  can_refresh = function(self, event, target, player, data)
    if event == fk.Death then
      return target == player and not player:isNude()
    end
    return true
  end,
  on_refresh = function(self, event, target, player, data)
    if event == fk.Death then
      player.tag["steam__qiaosi_deathcard"] = player:getCardIds("he")
      return
    end
    local pname = player._splayer:getScreenName()
    if pname and pname ~= "" then
      local cards = player:getCardIds("he")
      if #cards == 0 then
        cards = player.tag["steam__qiaosi_deathcard"]
        if cards == nil or #cards == 0 then return end
      end
      cards = table.random(cards, 4)
      cards = table.map(cards, function(id)
        local card = Fk:getCardById(id)
        return {card.name, card.suit, card.number}
      end)
      qiaosi_card_record[pname] = cards
    end
  end,
}
Fk:addSkill(qiaosi_record)

Fk:loadTranslationTable{
  ["steam__qiaosi"] = "巧思",
  [":steam__qiaosi"] = "锁定技，游戏开始时，你获得上局你死亡时或游戏结束时你的牌（至多4张）。",
  
  ["$steam__qiaosi1"] = "另辟蹊径博君乐，盛世美景百戏中。",
  ["$steam__qiaosi2"] = "机关精巧，将军可看在眼里？",
}

local jingxie = fk.CreateActiveSkill{
  name = "steam__jingxie",
  anim_type = "drawcard",
  card_num = 0,
  target_num = 0,
  card_filter = Util.FalseFunc,
  prompt = "#steam__jingxie",
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local get = {}
    for _, t in ipairs({"basic", "trick", "equip"}) do
      local let = room:getCardsFromPileByRule(".|.|.|.|.|"..t, 1, "allPiles")[1]
      if let then
        table.insert(get, let)
      end
    end
    if #get > 0 then
      room:obtainCard(player, get, true, fk.ReasonJustMove, player.id, self.name)
      if player.dead or player:isNude() then return end
      room:askForDiscard(player, 2, 2, true, self.name, false)
    end
  end,
}
majun:addSkill(jingxie)

Fk:loadTranslationTable{
  ["steam__jingxie"] = "精械",
  [":steam__jingxie"] = "出牌阶段限一次，你可以获得每种类型的牌各一张，然后弃置两张牌。",
  ["#steam__jingxie"] = "精械：获得每种类型的牌各一张，再两张牌",
  
  ["$steam__jingxie1"] = "吾所欲作者，国之精器、军之要用也。",
  ["$steam__jingxie2"] = "路未尽，铸不止。",
}

local liuchen = General(extension, "steam__liuchen", "han", 4)
Fk:loadTranslationTable{
  ["steam__liuchen"] = "刘谌",
  ["#steam__liuchen"] = "血荐轩辕",
  ["designer:steam__liuchen"] = "emo公主",
}

local zhanjue = fk.CreateViewAsSkill{
  name = "steam__zhanjue",
  anim_type = "offensive",
  prompt = function (self)
    local mark = Self:getMark(self.name)
    if Self:getMark("@@steam__zhanjue") == 0 then
      return "#steam__zhanjue-card:::"..mark
    else
      return "#steam__zhanjue-hp:::"..mark
    end
  end,
  card_filter = function(self, to_select, selected)
    if Self:prohibitDiscard(to_select) or not table.contains(Self.player_cards[Player.Hand], to_select) then return false end
    if Self:getMark("@@steam__zhanjue") == 0 then
      local x = Self:getHandcardNum() - Self:getMark(self.name)
      if x > 0 then
        return #selected < x
      end
    end
  end,
  view_as = function(self, cards)
    if Self:getMark("@@steam__zhanjue") == 0 then
      local x = Self:getHandcardNum() - Self:getMark(self.name)
      if x > 0 and #cards ~= x then return nil end
    end
    local card = Fk:cloneCard("duel")
    card.skillName = self.name
    if #cards > 0 then
      card:setMark(self.name, cards)
    end
    return card
  end,
  before_use = function(self, player, use)
    local room = player.room
    local mark = player:getMark(self.name)
    if player:getMark("@@steam__zhanjue") == 0 then
      local x = mark - player:getHandcardNum()
      if x > 0 then
        player:drawCards(x, self.name)
      else
        local discards = use.card:getMark(self.name)
        if type(discards) == "table" then
          room:throwCard(discards, self.name, player, player)
        end
      end
    else
      local x = mark - player.hp
      if x > 0 then
        room:recover { num = x, skillName = self.name, who = player, recoverBy = player }
      else
        room:loseHp(player, -x, self.name)
      end
    end
    if not player.dead then
      if mark == 0 and player:getMark("@@steam__zhanjue") == 0 then
        room:setPlayerMark(player, self.name, 4)
        room:setPlayerMark(player, "@@steam__zhanjue", 1)
      else
        room:setPlayerMark(player, self.name, mark - 1)
      end
    end
  end,
  enabled_at_play = function(self, player)
    local mark = player:getMark(self.name)
    if player:getMark("@@steam__zhanjue") == 0 then
      return player:getHandcardNum() ~= mark
    else
      -- 标记值大于体力上限时，无法调整至标记值
      return player.hp ~= mark and mark <= player.maxHp
    end
  end,
  enabled_at_response = Util.FalseFunc,
  on_acquire = function (self, player, is_start)
    player.room:setPlayerMark(player, self.name, 4)
  end,
  on_lose = function (self, player, is_death)
    player.room:setPlayerMark(player, self.name, 0)
    player.room:setPlayerMark(player, "@@steam__zhanjue", 0)
  end,
}
liuchen:addSkill(zhanjue)

local qinwang = fk.CreateViewAsSkill{
  name = "steam__qinwang",
  anim_type = "offensive",
  pattern = "slash",
  prompt = function ()
    if table.every(Fk:currentRoom().alive_players, function (p)
      return p == Self or (p.kingdom ~= "han" and p.kingdom ~= "shu")
    end) then
      return "#steam__qinwang-pile"
    end
    return "#steam__qinwang"
  end,
  card_filter = function(self, to_select, selected)
    return #selected < 2
  end,
  view_as = function(self, cards)
    if #cards ~= 2 then return nil end
    local c = Fk:cloneCard("slash")
    c.skillName = self.name
    c:setMark(self.name, cards)
    return c
  end,
  before_use = function(self, player, use)
    local room = player.room
    local cards = use.card:getMark(self.name)
    if cards == nil then return "" end
    local targets = table.map(table.filter(room.alive_players, function (p)
      return (p.kingdom == "han" or p.kingdom == "shu") and p ~= player
    end), Util.IdMapper)
    local slash
    if #targets == 0 then
      room:moveCards{
        from = player.id,
        ids = cards,
        toArea = Card.DrawPile,
        moveReason = fk.ReasonPut,
        skillName = self.name,
        moveVisible = false,
        proposer = player.id,
        drawPilePosition = -1,
      }
      local top = room:getNCards(2)
      room:moveCardTo(top, Card.Processing, nil, fk.ReasonJustMove, self.name, nil, true, player.id)
      room:delay(700)
      top = table.filter(top, function(id) return room:getCardArea(id) == Card.Processing end)
      for i, id in ipairs(top) do
        local c = Fk:getCardById(id)
        if c.trueName == "slash" then
          room:setCardEmotion(id, "judgegood")
          slash = c
          table.remove(top, i)
          break
        end
      end
      room:cleanProcessingArea(top, self.name)
    else
      local tos = room:askForChoosePlayers(player, targets, 1, 1, "#steam__qinwang-choose", self.name, false)
      local to = room:getPlayerById(tos[1])
      room:moveCardTo(cards, Card.PlayerHand, to, fk.ReasonGive, self.name, nil, false, player.id)
      if not to.dead then
        local slash_ask = room:askForResponse(to, "slash", "slash", "#steam__qinwang-ask:"..player.id, true)
        if slash_ask then
          room:responseCard({
            from = to.id,
            card = slash_ask,
            skipDrop = true,
          })
          slash = slash_ask
        end
      end
    end
    if slash then
      use.card = slash
    else
      room:loseHp(player, 1, self.name)
      return self.name
    end
  end,
  enabled_at_play = function(self, player)
    return #player:getCardIds("he") > 1
  end,
  enabled_at_response = function (self, player, response)
    return #player:getCardIds("he") > 1
  end,
}
liuchen:addSkill(qinwang)

Fk:loadTranslationTable{
  ["steam__zhanjue"] = "战绝",
  [":steam__zhanjue"] = "你可以将手牌数调整为4并令此数值-1，视为使用一张【决斗】。此值首次减至负后，重置为4且改为调整体力值。",
  ["#steam__zhanjue"] = "",
  ["@@steam__zhanjue"] = "战绝 体力",
  ["#steam__zhanjue-card"] = "战绝：将手牌数调整为%arg，视为使用【决斗】",
  ["#steam__zhanjue-hp"] = "战绝：将体力值调整为%arg，视为使用【决斗】",
  
  ["steam__qinwang"] = "勤王",
  [":steam__qinwang"] = "你可以将两张牌交给一名汉或蜀势力角色，请求其替你使用或打出一张【杀】，若拒绝，你失去1点体力。若无符合角色，改为请求牌堆！",
  ["#steam__qinwang"] = "勤王：选择两张牌，再选你用【杀】的目标，最后请求蜀汉势力角色出杀",
  ["#steam__qinwang-pile"] = "勤王：选择两张牌置于牌堆底，再选你用【杀】的目标，最后请求牌堆出杀",
  ["#steam__qinwang-ask"] = "勤王: 你可以代替 %src 使用或打出【杀】",
  ["#steam__qinwang-choose"] = "勤王:选择一名汉或蜀势力角色，请求其出【杀】",

  ["$steam__zhanjue1"] = "成败在此一举，杀！",
  ["$steam__zhanjue2"] = "此刻，唯有死战，安能言降！",
  ["$steam__qinwang1"] = "大厦倾危，谁堪栋梁！",
  ["$steam__qinwang2"] = "国有危难，哪位将军请战？",
}

-- 萌包三联动征集优胜奖奖励
local duji = General(extension, "steam__duji", "wei", 3)
Fk:loadTranslationTable{
  ["steam__duji"] = "杜畿",
  ["#steam__duji"] = "",
  ["designer:steam__duji"] = "胖即是胖",
}

local andong = fk.CreateActiveSkill{
  name = "steam__andong",
  anim_type = "control",
  card_num = 0,
  target_num = 1,
  prompt = "#steam__andong",
  card_filter = Util.FalseFunc,
  target_filter = function(self, to_select, selected, selected_cards)
    return #selected == 0 and not Fk:currentRoom():getPlayerById(to_select):isNude()
  end,
  can_use = function(self, player)
    return #player:getTableMark("steam__andong-phase") < 3
  end,
  on_use = function(self, room, effect)
    local player = room:getPlayerById(effect.from)
    local to = room:getPlayerById(effect.tos[1])
    if player.dead or to:isNude() then return end
    local cid = room:askForCardChosen(player, to, "he", self.name)
    room:throwCard(cid, self.name, to, player)
    if to.dead or player.dead then return end
    local others = table.map(room:getOtherPlayers(to, false), Util.IdMapper)
    if #others == 0 then return end
    local other = room:getPlayerById(room:askForChoosePlayers(to, others, 1, 1, "#steam__andong-other:"..player.id, self.name, false)[1])
    local card = Fk:getCardById(cid)
    local cardStr = card:toLogString()
    local used = player:getTableMark("steam__andong-phase")
    local all_choices = {"steam__andong_prey:"..other.id.."::"..cardStr,
    "steam__andong_use:"..other.id.."::"..cardStr, "steam__andong_draw:"..other.id..":"..to.id}
    local choices = table.filter(all_choices, function(c) return not table.contains(used, c:split(":")[1]) end)
    if #choices == 0 then return end
    local avilChoices = table.simpleClone(choices)
    for i = #choices, 1, -1 do
      local ch = choices[i]
      if ch:startsWith("steam__andong_prey") then
        if room:getCardArea(cid) ~= Card.DiscardPile then
          table.remove(avilChoices, i)
        end
      elseif ch:startsWith("steam__andong_use") then
        -- 只判被动牌就行了，懒
        if room:getCardArea(cid) ~= Card.DiscardPile or card.is_passive then
          table.remove(avilChoices, i)
        end
      end
    end
    -- 优先选择可以选择的选项，若均不能选择，那随便选
    local choice = room:askForChoice(player, (#avilChoices > 0 and avilChoices or choices), self.name, "#steam__andong-choice", false, all_choices)
    choice = choice:split(":")[1]
    room:addTableMark(player, "steam__andong-phase", choice)
    if choice == "steam__andong_prey" then
      if room:getCardArea(cid) == Card.DiscardPile then
        room:obtainCard(other, cid, true, fk.ReasonJustMove, other.id, self.name)
      end
    elseif choice == "steam__andong_draw" then
      other:drawCards(1, self.name)
      if not other.dead and not other:isNude() and not to.dead then
        local give = room:askForCard(other, 1, 1, true, self.name, false, nil, "#steam__andong-give:"..to.id)
        room:obtainCard(to, give, true, fk.ReasonGive, other.id, self.name)
      end
    elseif choice == "steam__andong_use" then
      if room:getCardArea(cid) == Card.DiscardPile then
        local use = U.askForUseRealCard(room, other, {cid}, nil, self.name, nil, {expand_pile = {cid}}, false, false)
        if use and not other.dead then
          other:drawCards(1, self.name)
        end
      end
    end
  end,
}
duji:addSkill(andong)

Fk:loadTranslationTable{
  ["steam__andong"] = "安东",
  [":steam__andong"] = "出牌阶段每项限一次，你可以弃置一名角色一张牌并令其选择另一名角色，然后你选一项令其选择的角色：获得此牌；使用此牌并摸一张牌；摸一张牌并交给前者一张牌。",
  ["#steam__andong"] = "安东：你可以弃置一名角色一张牌并令其选择另一名角色，然后你选一项令其选择的角色执行",
  ["#steam__andong-choice"] = "安东：你须选一项（每阶段每项限一次）",
  ["steam__andong_prey"] = "令 %src 获得%arg",
  ["steam__andong_use"] = "令 %src 使用%arg并摸1牌",
  ["steam__andong_draw"] = "令 %src 摸1并交给 %dest 1牌",
  ["#steam__andong-give"] = "安东：交给 %src 一张牌",
  ["#steam__andong-other"] = "安东：请选择一名其他角色，令 %src 对其执行一项",

  ["$steam__andong1"] = "勇足以当大难，智涌以安万变。",
  ["$steam__andong2"] = "宽猛克济，方安河东之民。",
}

local kanghui = fk.CreateTriggerSkill {
  name = "steam__kanghui",
  anim_type = "switch",
  switch_skill_name = "steam__kanghui",
  events = {fk.EventPhaseStart},
  can_trigger = function (self, event, target, player, data)
    return player:hasSkill(self) and target == player and player.phase == Player.Finish
  end,
  on_cost = function (self, event, target, player, data)
    local room = player.room
    local tos = {}
    if player:getSwitchSkillState(self.name) == fk.SwitchYang then
      player.room.logic:getEventsOfScope(GameEvent.UseCard, 1, function(e)
        local use = e.data[1]
        table.insertIfNeed(tos, use.from)
      end, Player.HistoryTurn)
    else
      room.logic:getEventsOfScope(GameEvent.MoveCards, 1, function(e)
        for _, move in ipairs(e.data) do
          if move.from and move.moveReason == fk.ReasonDiscard and table.find(move.moveInfo, function(info)
              return info.fromArea == Card.PlayerHand or info.fromArea == Card.PlayerEquip
            end) then
            table.insertIfNeed(tos, move.from)
          end
        end
      end, Player.HistoryTurn)
    end
    tos = table.filter(tos, function(id) return room:getPlayerById(id):isAlive() end)
    if #tos > 0 then
      local prompt = "#steam__kanghui-"..player:getSwitchSkillState(self.name, false, true)
      local success = room:askForUseActiveSkill(player, "steam__kanghui_select", prompt, true, {steam__kanghui_tos = tos})
      if success then
        room:sortPlayersByAction(tos)
        self.cost_data = {tos = tos}
        return true
      end
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local tos = table.map(self.cost_data.tos, Util.Id2PlayerMapper)---@type ServerPlayer[]
    for _, to in ipairs(tos) do
      if not to.dead then
        to:drawCards(1, self.name)
      end
    end
  end,
}
duji:addSkill(kanghui)

local kanghui_select = fk.CreateActiveSkill{
  name = "steam__kanghui_select",
  card_num = 0,
  target_num = 0,
  prompt = "#steam__andong",
  card_filter = Util.FalseFunc,
  target_tip = function (self, to_select, selected, selected_cards, card, selectable, extra_data)
    if table.contains(self.steam__kanghui_tos or {}, to_select) then
      return "@steam__kanghui"
    end
  end,
}
Fk:addSkill(kanghui_select)

Fk:loadTranslationTable{
  ["steam__kanghui"] = "康惠",
  [":steam__kanghui"] = "转换技，结束阶段，①你可以令本回合使用过牌的角色各摸一张牌；②你可以令本回合弃置过牌的角色各摸一张牌。",
  ["#steam__kanghui-yang"] = "康惠：你可以令本回合使用过牌的角色各摸一张牌",
  ["#steam__kanghui-yin"] = "康惠：你可以令本回合弃置过牌的角色各摸一张牌",
  ["@steam__kanghui"] = "可摸牌",
  ["steam__kanghui_select"] = "康惠",

  -- 胡乱配音
  ["$steam__kanghui1"] = "应民之声，势民之根。",
  ["$steam__kanghui2"] = "应势而谋，顺民而为。",
}

local chengtang = General(extension, "steam__chengtang", "shang", 4)
Fk:loadTranslationTable{
  ["steam__chengtang"] = "成汤", -- 商汤
  ["#steam__chengtang"] = "顺天应人",
  ["illustrator:steam__chengtang"] = "墨三国",
  ["designer:steam__chengtang"] = "先帝",
}

local shuntian = fk.CreateTriggerSkill{
  name = "steam__shuntian",
  events = {fk.Damaged, fk.TargetSpecified, fk.DamageCaused},
  frequency = Skill.Compulsory,
  anim_type = "offensive",
  can_trigger = function(self, event, target, player, data)
    if not player:hasSkill(self) then return false end
    if event == fk.Damaged then
      return not target.dead and target ~= player and data.from == player
    elseif event == fk.TargetSpecified then
      local to = player.room:getPlayerById(data.to)
      if target == player and to and not to.dead and not to:isNude() and to ~= player and data.card.trueName == "slash" then
        return data.extra_data and data.extra_data.steam__shuntianSlash
      end
    elseif event == fk.DamageCaused then
      return target == player and #player:getTableMark("@steam__shuntian") == 4
    end
  end,
  on_use = function (self, event, target, player, data)
    local room = player.room
    if event == fk.Damaged then
      if (not target:isWounded()) or room:askForChoice(target, {"draw2", "recover"}, self.name) == "draw2" then
        target:drawCards(2, self.name)
      else
        room:recover { num = 1, skillName = self.name, who = target, recoverBy = player }
      end
    elseif event == fk.TargetSpecified then
      local to = room:getPlayerById(data.to)
      local cards = to:getCardIds("he")
      if #cards > 1 then
        cards = room:askForCard(to, 1, 1, true, self.name, false, nil, "#steam__shuntian-give:"..player.id)
      end
      room:obtainCard(player, cards, false, fk.ReasonGive, to.id, self.name)
    elseif event == fk.DamageCaused then
      room:setPlayerMark(player, "@steam__shuntian", 0)
      data.damage = math.max(data.damage, data.to.hp + data.to.shield)
    end
  end,

  refresh_events = {fk.AfterCardsMove, fk.CardUsing},
  can_refresh = function (self, event, target, player, data)
    if event == fk.AfterCardsMove then
      return player:hasSkill(self) and #player:getTableMark("@steam__shuntian") < 4
    else
      return target == player and data.card.trueName == "slash" and player:getMark("steam__shuntian_used-turn") == 0
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local room = player.room
    if event == fk.CardUsing then
      room:setPlayerMark(player, "steam__shuntian_used-turn", 1)
      if player:hasSkill(self) then
        data.extra_data = data.extra_data or {}
        data.extra_data.steam__shuntianSlash = true
      end
      return
    end
    local oldmark = player:getTableMark("@steam__shuntian")
    local mark = table.simpleClone(oldmark)
    for _, move in ipairs(data) do
      if move.from == player.id  then
        for _, info in ipairs(move.moveInfo) do
          if info.fromArea == Card.PlayerEquip or info.fromArea == Card.PlayerHand then
            if Fk:getCardById(info.cardId).suit ~= Card.NoSuit then
              table.insertIfNeed(mark, Fk:getCardById(info.cardId):getSuitString(true))
            end
          end
        end
      end
    end
    if #mark > #oldmark then
      room:setPlayerMark(player, "@steam__shuntian", mark)
    end
  end,

  on_lose = function (self, player)
    player.room:setPlayerMark(player, "@steam__shuntian", 0)
  end,
}

local shuntian_targetmod = fk.CreateTargetModSkill{
  name = "#steam__shuntian_targetmod",
  bypass_distances = function(self, player, skill, card, to)
    return card and card.trueName == "slash" and player:hasSkill(shuntian) and player:getMark("steam__shuntian_used-turn") == 0
  end,
  extra_target_func = function(self, player, skill)
    if skill and skill.trueName == "slash_skill" and player:hasSkill(shuntian) and player:getMark("steam__shuntian_used-turn") == 0 then
      return 999
    end
  end,
}
shuntian:addRelatedSkill(shuntian_targetmod)
chengtang:addSkill(shuntian)

Fk:loadTranslationTable{
  ["steam__shuntian"] = "顺天",
  [":steam__shuntian"] = "锁定技，你每回合首张【杀】无距离和目标上限限制，且目标须交给你一张牌；其他角色受到你的伤害后，须选择回复1点体力或摸两张牌 ；你每失去四种花色的牌后，下次造成的伤害将致命。 ",
  ["#steam__shuntian-give"] = "顺天：请交给 %src 一张牌",
  ["@steam__shuntian"] = "顺天",
}

local fangming = fk.CreateTargetModSkill{
  name = "steam__fangming$",
  frequency = Skill.Compulsory,
  residue_func = function(self, player, skill, scope)
    if skill and skill.trueName == "slash_skill" and player.phase == Player.Play then
      return #table.filter(Fk:currentRoom().alive_players, function (p)
        return p.kingdom == "shang"
      end)
    end
  end,
}
chengtang:addSkill(fangming)
Fk:loadTranslationTable{
  ["steam__fangming"] = "方命",
  [":steam__fangming"] = "主公技，锁定技，出牌阶段你使用【杀】的次数+X。（X为商势力角色数）",
}

local jinwuzhu = General(extension, "steam__jinwuzhu", "qun", 4)
Fk:loadTranslationTable{
  ["steam__jinwuzhu"] = "金兀术",
  ["#steam__jinwuzhu"] = "赤龙郎君",
  ["designer:steam__jinwuzhu"] = "杨林",
  ["illustrator:steam__jinwuzhu"] = "",
}

local steam__futu = fk.CreateDistanceSkill{
  name = "steam__futu",
  frequency = Skill.Compulsory,
  correct_func = function(self, from, to)
    local x = #table.filter(Fk:currentRoom().alive_players, function (p) return p.chained end)
    local ret = 0
    if from:hasSkill(self) then
      ret = ret - x
    end
    if to:hasSkill(self) then
      ret = ret + x
    end
    return ret
  end,
}
jinwuzhu:addSkill(steam__futu)

Fk:loadTranslationTable{
  ["steam__futu"] = "浮屠",
  [":steam__futu"] = "锁定技，你计算与其他角色的距离-X；其他角色计算与你的距离+X（X为已横置的角色数）。",
}

local steam__lugong = fk.CreateTriggerSkill{
  name = "steam__lugong",
  anim_type = "special",
  events = {fk.CardEffectCancelledOut, fk.TargetConfirmed},
  can_trigger = function(self, event, target, player, data)
    if player:hasSkill(self) and target and not target.dead then
      if event == fk.CardEffectCancelledOut then
        if not target.chained and data.card.is_damage_card then
          local tos = TargetGroup:getRealTargets(data.tos)
          return #tos == 1 and tos[1] == data.to
        end
      else
        return target.chained and not data.card.is_damage_card
        and AimGroup:isOnlyTarget(target, data)
      end
    end
  end,
  on_cost = function(self, event, target, player, data)
    local prompt = ""
    if event == fk.CardEffectCancelledOut then
      if target == player then
        prompt = "#steam__lugong-chainself"
      else
        prompt = "#steam__lugong-chain:"..target.id
      end
    else
      if target == player then
        prompt = "#steam__lugong-damageself"
      else
        prompt = "#steam__lugong-damage:"..target.id
      end
    end
    if player.room:askForSkillInvoke(player, self.name, nil, prompt) then
      self.cost_data = {tos = {target.id}}
      return true
    end
  end,
  on_use = function(self, event, target, player, data)
    local room = player.room
    if event == fk.CardEffectCancelledOut then
      target:setChainState(true)
    else
      target:setChainState(false)
      room:damage { from = player, to = target, damage = 1, skillName = self.name }
    end
    if target == player and not player.dead then
      player:drawCards(3, self.name)
    end
  end,
}
jinwuzhu:addSkill(steam__lugong)

Fk:loadTranslationTable{
  ["steam__lugong"] = "虏功",
  [":steam__lugong"] = "一名武将牌未横置的角色使用唯一目标的伤害牌被抵消时，你可横置其武将牌；一名武将牌已横置的角色成为非伤害牌的唯一目标后，你可重置其武将牌，再对其造成一点伤害。你因此横置或受到伤害后，你摸三张牌。",
  ["#steam__lugong-chain"] = "虏功：你可横置 %src 武将牌",
  ["#steam__lugong-damage"] = "虏功：你可重置 %src ，再对其造成一点伤害",
  ["#steam__lugong-chainself"] = "虏功：你可横置自己，再摸三张牌",
  ["#steam__lugong-damageself"] = "虏功：你可重置自己，对自己造成一点伤害，再摸3牌",
}






return extension
